CF1748C Zero-Sum Prefixes
有意思的统计题。
Description
给你一个长度为 \(n\) 的整数序列 \(A\),你可以将其中的 \(0\) 替换为任意的 \(x(x\in\mathbb{Z})\)。
问经替换后最多有多少个 \(i\) 满足 \(\sum^{i}_{j=1}a_j=0\)。
Analysis
考虑每一个 \(0\) 可以控制到下一个 \(0\) 之间的前缀和 \(=0\) 数。这点容易想到,于是发现分段处理。
对每两个 \(0\) 之间的位置求前缀和众数(可以使用 Hash 或 std:: map),设众数为 \(x\),则前面的 \(0\) 可以替换为 \(-x\) 以得最优解。
注意:第一个 \(0\) 前的原始为 \(0\) 的前缀和不要漏统。
Code
#include <stdio.h>
#include <map>
#define int long long
const int N = (int)2e5 + 5;
int n, a[N], s[N];
inline void Solve() {
scanf("%lld", &n); s[0] = 0;
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
s[i] = s[i - 1] + a[i];
}
int ans = 0, st;
for (st = 1; st <= n && a[st]; ++st)
if (!s[st]) ++ans;
for (int i = st, j; i <= n; i = j) {
std:: map<int, int> cnt; int now = 1;
for (j = i + 1; j <= n && a[j]; ++j);
for (int k = i; k < j; ++k) {
++cnt[s[k]];
if (cnt[s[k]] > now) now = cnt[s[k]];
}
ans += now;
}
printf("%lld\n", ans);
}
signed main(void) {
int T; for (scanf("%lld", &T); T--; ) Solve();
return 0;
}
Postscript
至今不知道为什么写成 unordered_map 会超时,
但写成 map 肯定能过。
不说再见

浙公网安备 33010602011771号