具体见http://blog.csdn.net/PoPoQQQ/article/details/42193259
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #define maxn 262144 7 #define pi 3.14159265358979323846 8 #define mod 1000000007 9 using namespace std; 10 char s[maxn],ss[maxn]; 11 bool ok; 12 int ans,ans1,len,m,n,id,pow2[maxn],f[maxn],g[maxn]; 13 struct comp{ 14 double rea,ima; 15 void clear(){rea=ima=0;} 16 comp operator +(const comp &x){return (comp){rea+x.rea,ima+x.ima};} 17 comp operator -(const comp &x){return (comp){rea-x.rea,ima-x.ima};} 18 comp operator *(const comp &x){return (comp){rea*x.rea-ima*x.ima,rea*x.ima+ima*x.rea};} 19 }a[maxn],c[maxn],tmp[maxn],w,wn; 20 void fft(comp *a,int st,int siz,int step,int op){ 21 if (siz==1) return; 22 fft(a,st,siz>>1,step<<1,op),fft(a,st+step,siz>>1,step<<1,op); 23 int x=st,x1=st,x2=st+step; 24 w=(comp){1,0},wn=(comp){cos(op*2*pi/siz),sin(op*2*pi/siz)}; 25 for (int i=0;i<(siz>>1);i++,x+=step,x1+=(step<<1),x2+=(step<<1),w=w*wn) 26 tmp[x]=a[x1]+(w*a[x2]),tmp[x+(siz>>1)*step]=a[x1]-(w*a[x2]); 27 for (int i=st;siz;i+=step,siz--) a[i]=tmp[i]; 28 } 29 void manacher(){ 30 m=(len<<1)+1,ss[1]='#',id=0; 31 for (int i=1;i<=len;i++) ss[i<<1]=s[i],ss[(i<<1)+1]='#'; 32 for (int i=1;i<=m;i++){ 33 f[i]=(id+f[id]>=i)?min(f[(id<<1)-i],id+f[id]-i):0; 34 while (i-f[i]-1>=1&&i+f[i]+1<=m&&ss[i-f[i]-1]==ss[i+f[i]+1]) f[i]++; 35 if (i+f[i]>id+f[id]) id=i; 36 ans+=((f[i]+1)>>1),ans%=mod; 37 } 38 } 39 int main(){ 40 scanf("%s",s+1); n=1,pow2[0]=1; 41 len=strlen(s+1),manacher(); 42 while (n<(len<<1)) n<<=1; 43 for (int i=1;i<n;i++) pow2[i]=(pow2[i-1]<<1)%mod; 44 for (int i=1;i<=len;i++) a[i].rea=(s[i]=='a'); 45 fft(a,0,n,1,1); 46 for (int i=0;i<n;i++) c[i]=a[i]*a[i]; 47 for (int i=0;i<n;i++) a[i].clear(); 48 for (int i=1;i<=len;i++) a[i].rea=(s[i]=='b'); 49 fft(a,0,n,1,1); 50 for (int i=0;i<n;i++) c[i]=c[i]+a[i]*a[i]; 51 fft(c,0,n,1,-1); 52 for (int i=0;i<n;i++) g[i]+=(int)round(c[i].rea/n); 53 for (int i=0;i<n;i++) ans1+=pow2[(g[i]+1)>>1]-1,ans1%=mod; 54 ans1-=ans,ans1%=mod,ans1+=mod,ans1%=mod; 55 printf("%d ",ans1); 56 system("pause"); 57 return 0; 58 }