[51nod 1393] 0和1相等串 前缀和

#include<cstdio>
#include<cstring>
#define maxn 1000050
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int l[maxn<<1];// 即maxn*2
int a[maxn];
char s[maxn];
int main(){
    scanf("%s",s+1);
    int n=strlen(s+1);
    for (int i=1;i<=n;i++)
    a[i]=a[i-1]+(s[i]=='1'?1:-1);
    for (int i=0;i<=n+n;i++)
    l[i]=-1; //初始化为-1
    l[0+n]=0;//a[0]=0  +n是因为所有数都+n以保证为非负数
    int ans=0;
    for (int i=1;i<=n;i++){
        if (l[a[i]+n]<0) l[a[i]+n]=i;//
        ans=max(ans,i-l[a[i]+n]);
    }
    printf("%d\n",ans);
}
/*
记1是+1 0是-1
然后做一次前缀和
a[i]=a[i-1]+(s[i]=='1'?1:-1)
可以发现对于一个区间[l,r]
如果满足0的个数等于1的个数
那么这段区间的和一定是0
即满足a[r]-a[l-1]=0
也就是a[r]=a[l-1]
考虑枚举 r
那么我们希望找到一个最小的l
使得a[l-1]=a[r] ->此时贡献为r-l+1

我们可以利用一个数组l[x]来记录
a[i]=x的最小i
那么枚举r时
ans=max(ans,r-l[a[r]])

考虑到a[i]可能为负数,可以考虑加上n来保证a[i]是正的
这样就可以作为数组下标了

*/

 

posted @ 2022-10-10 23:22  Bunnycxk  阅读(86)  评论(0编辑  收藏  举报