一眼看去,有点像LOJ2427,然后。。那是想多了
好像没有什么好办法
仔细分析一下:
- 首先显然只有偶数串才能成功
- 而且假如 [L,R] [ L , R ] 成功了,则 [L+1,R−1] [ L + 1 , R − 1 ] 一定成功
这样不就可以hash+二分枚举了吗?
#include<bits/stdc++.h>
#define gt() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
#define LL long long
#define __R
#define isnum(ch) (ch=='0'||ch=='1')
using namespace std;
int Top;static char St[1000000],buf[1000000],*p1=buf,*p2=buf;
const int maxn=(5e5)+5,bas=233;
int n;bool a[maxn];LL L[maxn],R[maxn],Pow[maxn],Ans;
int main(){
scanf("%d",&n);char ch=gt();
while(!isnum(ch)) ch=gt();Pow[0]=1;
for(__R int i=1;i<=n;i++,ch=gt()) L[i]=L[i-1]*bas+(a[i]=ch-'0'),Pow[i]=Pow[i-1]*bas;
for(__R int i=n;i;i--) R[i]=R[i+1]*bas+(!a[i]);
int l,r,mid;
for(__R int i=1;i<n;i++)if(a[i]!=a[i+1]){
l=1,r=n-i<i?n-i:i;
while(l<=r){
mid=l+r>>1;
if(L[i]-L[i-mid]*Pow[mid]==R[i+1]-R[i+mid+1]*Pow[mid]) l=mid+1;else r=mid-1;
}
Ans+=r;
}
printf("%lld\n",Ans);
return 0;
}