CF873B Balanced Substring
阿新 • • 發佈:2018-11-11
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; }