https://www.cnblogs.com/zhoushuyu/p/8672807.html
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 using namespace std; 7 8 const int N=400010,mod=1e9+7; 9 const double pi=acos(-1.); 10 int n,len,ans,L,mx,id,bin[N],rev[N],f[N],p[N]; 11 char s[N],tmp[N]; 12 13 struct C{ 14 double x,y; 15 C(double _x=0,double _y=0):x(_x),y(_y){} 16 C operator +(C &b){ return C(x+b.x,y+b.y); } 17 C operator -(C &b){ return C(x-b.x,y-b.y); } 18 C operator *(C &b){ return C(x*b.x-y*b.y,x*b.y+b.x*y); } 19 }a[N]; 20 21 void FFT(C a[],int f){ 22 for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]); 23 for (int i=1; i<n; i<<=1){ 24 C wn=C(cos(pi/i),f*sin(pi/i)); 25 for (int p=i<<1,j=0; j<n; j+=p){ 26 C w(1,0); 27 for (int k=0; k<i; k++,w=w*wn){ 28 C x=a[j+k],y=w*a[i+j+k]; a[j+k]=x+y; a[i+j+k]=x-y; 29 } 30 } 31 } 32 if (f==-1) for (int i=0; i<n; i++) a[i].x/=n; 33 } 34 35 void work(char ch){ 36 for (int i=0; i<n; i++) a[i]=C(s[i]==ch,0); 37 FFT(a,1); for (int i=0; i<n; i++) a[i]=a[i]*a[i]; FFT(a,-1); 38 rep(i,2,len<<1) f[i]+=((int)(a[i].x+0.5)+1)/2; 39 } 40 41 int main(){ 42 freopen("bzoj3160.in","r",stdin); 43 freopen("bzoj3160.out","w",stdout); 44 scanf("%s",s+1); len=strlen(s+1); 45 bin[0]=1; rep(i,1,len) bin[i]=(bin[i-1]<<1)%mod; 46 for (n=1; n<=(len<<1); n<<=1) ++L; 47 for (int i=0; i<n; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1)); 48 work('a'); work('b'); 49 rep(i,2,len<<1) ans=(ans+bin[f[i]]-1)%mod; 50 rep(i,1,len) tmp[i]=s[i]; 51 s[0]='$'; s[1]='#'; 52 rep(i,1,len) s[i<<1]=tmp[i],s[(i<<1)|1]='#'; 53 rep(i,1,len<<1){ 54 p[i]=(mx>i) ? min(p[2*id-i],mx-i) : 1; 55 while (s[i-p[i]]==s[i+p[i]]) p[i]++; 56 if (i+p[i]>mx) mx=i+p[i],id=i; 57 } 58 rep(i,1,len<<1) ans=(ans-p[i]/2+mod)%mod; 59 printf("%d ",ans); 60 return 0; 61 }