1 条题解
-
0
桶+后缀和
问题转化:由于只能使用两种颜色,且同色必须连续,整个围栏会被分成两个连续段,每段一种颜色。
前缀和处理:
计算后缀和数组sum,其中sum[i]表示最大涂刷数量大于等于i的颜色种类数。
计算方案数:
遍历所有可能的分段点i(1≤i≤m-1),将围栏分为长度为i和m-i的两段。
对于分段点i,需要找到两种颜色,一种能涂刷至少i块木板,另一种能涂刷至少m-i块木板。
方案数为:能涂刷至少i块的颜色数 × 能涂刷至少m-i块的颜色数 - 重复计算的部分。
#include<bits/stdc++.h> using namespace std; #define int long long #define endl '\n' #define pb push_back #define pp pop_back #define io() ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) const int N = 2e5 + 5; int a[N], sum[N]; void solve() { memset(sum, 0, sizeof sum); int m, n; cin >> m >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; sum[a[i]]++; } for (int i = m; i >= 1; i--) { sum[i] += sum[i + 1]; } long long ans = 0; for (int i = 1; i < m; i++) { int x = min(i, m - i), y = max(i, m - i); ans += sum[x] * sum[y] - sum[y]; // cout << x << " " << y << " : " << sum[x] * sum[y] - sum[y] * sum[y] << endl; } cout << ans << endl; } signed main() { // io(); int _ = 1; cin >> _; for (; _--;) solve(); return 0; }
- 1
信息
- ID
- 528
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 2
- 上传者