CF873B Balanced Substring

1到n内0,1个数相同的个数的最长字串
\(i>=j\)

\[1的个数=0的个数 \]

\[sum[i]-sum[j-1]=i-(j-1) - (sum[i]-sum[j-1]) \]

这里把\((j-1)\)替换为\(j\)

\[2*sum[i]-2*sum[j]=i-j \]

\[2*sum[i]-i=2*sum[j]-j \]

枚举i,然后求前面和\(2*sum[i]-i\)相同的最小标号
这里可能有负数,所以map就好了
当然,因为\(2*sum[i]-i\)的值是在区间[-n,n]的
所以你可以直接+n用数组桶一下
不告诉你我写过线段树

#include <bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=1e5+7;
const int inf=0x3f3f3f3f;
int n,a[maxn],sum[maxn];
//map<int,int> mi;
int mi[maxn*2];
int main()
{
	scanf("%d",&n);
	FOR(i,1,n) scanf("%1d",&a[i]),sum[i]=sum[i-1]+a[i];
	int ans=0;
	memset(mi,inf,sizeof(mi)); 
	mi[n]=0;
	FOR(i,1,n) {
		int tmp=n+2*sum[i]-i;
		int zz=mi[tmp];
//		if(!zz&&tmp!=0) zz=inf,mi[tmp]=inf;
		ans=max(i-zz,ans);
		mi[tmp]=min(zz,i);
	}
	cout<<ans;
	return 0;
}
posted @ 2018-10-17 20:22  ComplexPug  阅读(165)  评论(3编辑  收藏  举报