codeforces 873B - Balanced Substring (前缀和)
题目链接:https://codeforces.com/problemset/problem/873/B
小trick :把 0 看成 -1,求前缀和,
如果区间\([l,r]\)内 0 和 1 数量相等,那么\(sum[r] = sum[l-1]\)
所以只需要记录相同 sum 值出现的最小位置
注意开的记录\(bas[i]\)数组下标可能溢出,要先加上 100000
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 100010;
int n;
int a[maxn],sum[maxn],bas[maxn * 2];
char s[maxn];
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
memset(bas,-1,sizeof(bas));
n = read();
scanf("%s",s+1);
for(int i=1;i<=n;++i){
if(s[i] == '0') a[i] = -1;
else a[i] = 1;
}
int ans = 0;
sum[0] = 100000;
bas[sum[0]] = 0;
for(int i=1;i<=n;++i){
sum[i] = sum[i-1] + a[i];
if(bas[sum[i]] != -1){
ans = max(ans, i - bas[sum[i]]);
}else{
bas[sum[i]] = i;
}
}
// for(int i=1;i<=n;++i) printf("%d ",sum[i]); printf("\n");
printf("%d\n",ans);
return 0;
}