# bzoj3160 万径人踪灭

 1 //It is made by wfj_2048~
2 #include <algorithm>
3 #include <iostream>
4 #include <complex>
5 #include <cstring>
6 #include <cstdlib>
7 #include <cstdio>
8 #include <vector>
9 #include <cmath>
10 #include <queue>
11 #include <stack>
12 #include <map>
13 #include <set>
14 #define rhl (1000000007)
15 #define NN (1000010)
16 #define inf (1<<30)
17 #define pi acos(-1)
18 #define il inline
19 #define RG register
20 #define ll long long
21 #define C complex <double>
22
23 using namespace std;
24
25 int p[NN],f[NN],bin[NN],rev[NN],n,nn,N,lg;
26 char s[NN],c[NN];
27 C a[NN],b[NN];
28 ll ans,res;
29
30 il int gi(){
31     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
32     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
33 }
34
35 il ll manacher(){
36     RG int id=1,mx=1; RG ll ans=0; p[1]=1;
37     for (RG int i=2;i<nn;++i){
38     if (i<mx) p[i]=min(p[(id<<1)-i],mx-i); else p[i]=1;
39     while (i-p[i]>=0 && s[i+p[i]]==s[i-p[i]]) p[i]++;
40     if (mx<i+p[i]) mx=i+p[i],id=i;
41     ans+=(p[i]>>1); if (s[i]!='#') ans--;
42     }
43     return ans%rhl;
44 }
45
46 il void fft(C *a,RG int n,RG int f){
47     for (RG int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]);
48     for (RG int i=1;i<n;i<<=1){
49     C wn(cos(pi/i),sin(f*pi/i)),x,y;
50     for (RG int j=0;j<n;j+=(i<<1)){
51         C w(1,0);
52         for (RG int k=0;k<i;++k,w*=wn){
53         x=a[j+k],y=w*a[j+k+i];
54         a[j+k]=x+y,a[j+k+i]=x-y;
55         }
56     }
57     }
58     return;
59 }
60
61 il void work(){
62     scanf("%s",c+1),n=strlen(c+1); s[0]='#';
63     for (RG int i=1;i<=n;++i) s[i<<1]='#',s[(i<<1)-1]=c[i];
64     nn=(n<<1)+1,s[nn]='&'; for (N=1;N<=(nn<<1);N<<=1) lg++;
65     for (RG int i=0;i<=N;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
66     for (RG int i=0;i<N;++i) a[i]=s[i]=='a'; fft(a,N,1);
67     for (RG int i=0;i<N;++i) b[i]=a[i]*a[i],a[i]=s[i]=='b';
68     fft(a,N,1); for (RG int i=0;i<N;++i) b[i]+=a[i]*a[i]; fft(b,N,-1);
69     bin[0]=1; for (RG int i=1;i<=nn;++i){ bin[i]=bin[i-1]<<1; if (bin[i]>=rhl) bin[i]-=rhl; }
70     for (RG int i=1;i<nn;++i){
71     f[i]=((int)(b[i<<1].real()/N+0.5)-(s[i]!='#'))>>1;
72     res=bin[f[i]]-1; if (s[i]!='#') ans+=2*res; else ans+=res;
73     if (ans>=rhl) ans-=rhl;
74     }
75     printf("%lld\n",(ans-manacher()+rhl)%rhl); return;
76 }
77
78 int main(){
79     work();
80     return 0;
81 }

posted @ 2017-03-18 11:36  wfj_2048  阅读(175)  评论(0编辑  收藏  举报