「BZOJ3160」万径人踪灭

注意manacher的写法 注释掉的是TLE的代码

1
#include<bits/stdc++.h> 2 #define ll long long 3 #define db double 4 using namespace std; 5 const int N=150010; 6 const ll mod=1e9+7; 7 const db PI=acos(-1); 8 struct Complex{ 9 db real,image; 10 Complex(db _real=0,db _image=0):real(_real),image(_image){} 11 Complex operator+(Complex k)const{return Complex(real+k.real,image+k.image);} 12 Complex operator-(Complex k)const{return Complex(real-k.real,image-k.image);} 13 Complex operator*(Complex k)const{return Complex(real*k.real-image*k.image,real*k.image+image*k.real);} 14 Complex operator/(int k)const{return Complex(real/k,image/k);} 15 }a[N<<1],b[N<<1]; 16 int n,m,l,maxp,f[N<<1],rev[N<<1],pow2[N<<1]; 17 char s[N]; 18 void fft(Complex* x,int f){//f=1时为fft,f=-1时为ifft 19 for(int i=0;i<n;i++) if(rev[i]>i) swap(x[i],x[rev[i]]); 20 for(int len=1;len<n;len<<=1){ 21 Complex wn(cos(PI/len),f*sin(PI/len)); 22 for(int now=0;now<n-1;now+=(len<<1)){ 23 Complex w(1,0); 24 for(int i=0;i<len;i++,w=w*wn){ 25 Complex t1=x[now+i],t2=w*x[now+len+i]; 26 x[now+i]=t1+t2,x[now+len+i]=t1-t2; 27 } 28 } 29 } 30 if(f==-1) for(int i=0;i<n;i++) x[i]=x[i]/n; 31 return; 32 } 33 int maxr,pos,r[N<<1]; 34 //int manacher(){ 35 // int ans=0; 36 // s2[l2++]='#'; 37 // for(int i=0;i<l;i++) s2[l2++]=s[i],s2[l2++]='#'; 38 // for(int i=0;i<l2;i++){ 39 // r[i]=(maxr>=i)?min(maxr-i+1,r[(pos<<1)-i]):1; 40 // while(i-r[i]>=0&&i+r[i]<l2&&s2[i-r[i]]==s2[i+r[i]]) r[i]++; 41 // if(r[i]>maxr) maxr=r[i],pos=i; 42 // ans=ans+(r[i]>>1); 43 // if(ans>mod) ans-=mod; 44 // } 45 // return ans; 46 //} 47 int manacher(){ 48 int ans=0; 49 s[l+1]='#',s[0]='$'; 50 for(int i=1;i<=l;i++){ 51 if(maxr>i) r[i]=min(maxr-i+1,r[pos*2-i]); 52 else r[i]=1; 53 while(s[i+r[i]]==s[i-r[i]]) r[i]++; 54 if(i+r[i]-1>maxr) maxr=i+r[i]-1,pos=i; 55 ans=(ans+r[i])%mod; 56 } 57 maxr=0; 58 for(int i=1;i<=l;i++){ 59 if(maxr>i) r[i]=min(maxr-i,r[pos*2-i]); 60 else r[i]=0; 61 while(s[i+r[i]+1]==s[i-r[i]]) r[i]++; 62 if(i+r[i]>maxr) maxr=i+r[i],pos=i; 63 ans=(ans+r[i])%mod; 64 } 65 return ans; 66 } 67 int main(){ 68 scanf("%s",s+1); 69 l=strlen(s+1),n=l-1; 70 m=n<<1; 71 for(n=1;n<=m;n<<=1) maxp++; 72 for(int i=1;i<n;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(maxp-1)); 73 for(int i=1;i<=l;i++) a[i-1].real=(s[i]=='a'),b[i-1].real=(s[i]=='b'); 74 fft(a,1);fft(b,1); 75 for(int i=0;i<n;i++) a[i]=a[i]*a[i],b[i]=b[i]*b[i]; 76 fft(a,-1);fft(b,-1); 77 pow2[0]=1,f[0]=int(a[0].real+b[0].real+1.1)>>1; 78 for(int i=1;i<n;i++){ 79 pow2[i]=pow2[i-1]<<1,f[i]=int(a[i].real+b[i].real+1.1)>>1; 80 if(pow2[i]>=mod) pow2[i]-=mod; 81 } 82 ll ans=0; 83 for(int i=0;i<n;i++) ans=(ans+pow2[f[i]]-1)%mod; 84 int temp=manacher(); 85 ans-=temp; 86 if(ans<0) ans+=mod; 87 printf("%lld",ans); 88 return 0; 89 }

 

posted @ 2018-03-08 13:14  Cupcake  阅读(123)  评论(0编辑  收藏  举报