# BZOJ 3160 万径人踪灭 (FFT+manacher)

  1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #define N1 (1<<18)+10
6 #define M1 40010
7 #define ll long long
8 #define dd double
9 #define inf 0x3f3f3f3f
10 using namespace std;
11
12 int gint()
13 {
14     int ret=0,fh=1;char c=getchar();
15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
17     return ret*fh;
18 }
19 const dd pi=acos(-1);
20 const ll mod=1000000007;
21 ll qpow(ll x,ll y)
22 {
23     ll ans=1;
24     for(;y;x=x*x%mod,y>>=1)
25         if(y&1) ans=ans*x%mod;
26     return ans;
27 }
28 struct cp{
29 dd x,y;
30 friend cp operator + (const cp &s1,const cp &s2){ return (cp){s1.x+s2.x,s1.y+s2.y}; }
31 friend cp operator - (const cp &s1,const cp &s2){ return (cp){s1.x-s2.x,s1.y-s2.y}; }
32 friend cp operator * (const cp &s1,const cp &s2){ return (cp){s1.x*s2.x-s1.y*s2.y,s1.y*s2.x+s1.x*s2.y}; }
33 }A[N1],B[N1],C[N1];
34
35 void init()
36 {
37     memset(A,0,sizeof(A));
38     memset(B,0,sizeof(B));
39     memset(C,0,sizeof(C));
40 }
41
42 int r[N1];
43 void FFT(cp *s,int len,int type)
44 {
45     int i,j,k;
46     for(i=0;i<len;i++) if(i<r[i]) swap(s[i],s[r[i]]);
47     for(k=2;k<=len;k<<=1)
48     {
49         cp wn=(cp){cos(2.0*pi*type/k),sin(2.0*pi*type/k)},w,t;
50         for(i=0;i<len;i+=k)
51         {
52             w=(cp){1,0};
53             for(j=0;j<(k>>1);j++,w=w*wn)
54             {
55                 t=w*s[i+j+(k>>1)];
56                 s[i+j+(k>>1)]=s[i+j]-t;
57                 s[i+j]=s[i+j]+t;
58             }
59         }
60     }
61 }
62 void FFT_Main(int len)
63 {
64     FFT(A,len,1); FFT(B,len,1);
65     for(int i=0;i<len;i++) C[i]=A[i]*B[i];
66     FFT(C,len,-1);
67     for(int i=0;i<len;i++) C[i].x/=len;
68 }
69
70 int n,m,len,L,f[N1];
71 char str[N1],sstr[N1];
72 ll ans[N1];
73
74
75 int main()
76 {
77     scanf("%s",str); n=strlen(str);
78     int i,mr,mid; ll ret=0,tmp=0;
79     for(len=1,L=0;len<n+n;len<<=1,L++);
80     for(i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));
81
82     for(i=0;i<n;i++) A[i].x=(str[i]=='a'),B[i].x=(str[i]=='a');
83     FFT_Main(len);
84     for(i=0;i<n;i++) ans[i+2]+=((int)(C[i].x+0.1))/2;
85
86     init();
87     for(i=0;i<n;i++) A[i].x=(str[i]=='b'),B[i].x=(str[i]=='b');
88     FFT_Main(len);
89     for(i=0;i<n;i++) ans[i+2]+=((int)(C[i].x+0.1))/2;
90
91     init();
92     for(i=0;i<n;i++) A[i].x=(str[n-i-1]=='a'),B[i].x=(str[n-i-1]=='a');
93     FFT_Main(len);
94     for(i=0;i<n;i++) ans[2*n-i]+=((int)(C[i].x+0.1))/2;
95
96     init();
97     for(i=0;i<n;i++) A[i].x=(str[n-i-1]=='b'),B[i].x=(str[n-i-1]=='b');
98     FFT_Main(len);
99     for(i=0;i<n;i++) ans[2*n-i]+=((int)(C[i].x+0.1))/2;
100
101     ans[n+1]/=2;
102     mr=2,mid=1,f[1]=1;
103     for(i=0,sstr[0]='\$',sstr[1]='#';i<n;i++)
104         sstr[(i+1)<<1]=str[i],sstr[(i+1)<<1|1]='#';
105     for(i=2;i<=2*n+1;i++)
106     {
107         if(i<mr) f[i]=min(f[2*mid-i],mr-i);
108         else f[i]=1;
109         while(sstr[i-f[i]]==sstr[i+f[i]]) f[i]++;
110         if(i+f[i]>mr)
111             mr=i+f[i],mid=i;
112     }
113     for(i=1;i<=2*n+1;i++)
114        ret=(ret+qpow(2,ans[i]+(!(i&1)))-1-(f[i]-(i&1))/2+mod)%mod;
115     printf("%lld\n",ret);
116     return 0;
117 }

posted @ 2019-01-25 21:02  guapisolo  阅读(132)  评论(0编辑  收藏  举报