牛客多校第三场B
https://ac.nowcoder.com/acm/contest/883/B
比赛的时候二分找答案O(nlogn)
赛后发现可以O(n)
思路:
用一个区间维护前缀和
另取一个区间用前缀和为下标,以相同前缀和的最小下标为该位置的值,剩余前缀和位置减去该值可得长度,取最大值,不断更新答案
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
string a;
int n;
int pos[200005], cnt[200005];
int x, y;
int ans1, ans2;
int main() {
cin >> n >> a;
memset(pos, 0, sizeof(pos));
cnt[0] = 100000;
x = y = 0;
ans1 = ans2 = 0;
for (int i = 1; i <= n; i++) {
if (a[i - 1] == '0') {
cnt[i] = cnt[i - 1] - 1;
x++;
}
else {
cnt[i] = cnt[i - 1] + 1;
y++;
}
if (pos[cnt[i]] == 0 && cnt[i] != 100000) {
pos[cnt[i]] = i;
}
else {
ans1 = max(ans1, i - pos[cnt[i]]);
}
}
ans2 = min(x, y) * 2;
cout << ans1 << " " << ans2 << endl;
}