LOJ2452

LOJ2452

一眼看去,有点像LOJ2427,然后。。那是想多了
好像没有什么好办法
仔细分析一下:

  • 首先显然只有偶数串才能成功
  • 而且假如 [L,R] [ L , R ] 成功了,则 [L+1,R1] [ L + 1 , R − 1 ] 一定成功

这样不就可以hash+二分枚举了吗?

#include
#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;iif(a[i]!=a[i+1]){
        l=1,r=n-iwhile(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;
}

你可能感兴趣的:(LOJ,哈希,二分)