# bzoj3160万径人踪灭

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\n",ans1);
56     system("pause");
57     return 0;
58 }

posted @ 2015-07-21 10:24  chenyushuo  阅读(156)  评论(0编辑  收藏  举报