bzoj3160: 万径人踪灭

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int maxn=270010,mod=1000000007;
const double pi=M_PI;
using namespace std;
struct plex{
double r,i;
}tmp[maxn];

plex operator +(plex a,plex b){return (plex){a.r+b.r,a.i+b.i};}
plex operator -(plex a,plex b){return (plex){a.r-b.r,a.i-b.i};}
plex operator *(plex a,plex b){return (plex){a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r};}

struct DFT{
plex a[maxn];
void fft(int bg,int step,int size,int op){
if (size==1) return;
fft(bg,step<<1,size>>1,op),fft(bg+step,step<<1,size>>1,op);
plex w=(plex){1,0},t=(plex){cos(2*pi/size),sin(2*pi*op/size)};
int p=bg,p0=bg,p1=bg+step;
for (int i=0;i<size/2;i++){
tmp[p]=a[p0]+w*a[p1];
tmp[p+size/2*step]=a[p0]-w*a[p1];
p+=step,p0+=step*2,p1+=step*2,w=w*t;
}
for (int i=bg;size;size--,i+=step) a[i]=tmp[i];
}
}a,b;
int f[maxn<<1],len,n,nn,POW[maxn],ans;char str[maxn],s[maxn<<1];

int manacher(){
int i,res=0;
for (s[0]='\$',s[1]='#',i=1;i<=n;i++) s[i<<1]=str[i-1],s[(i<<1)|1]='#';
n=(n<<1)|1;
int mx=1,id=1;
for (int i=1;i<=n;i++){
f[i]=min(f[id+id-i],mx-i);
for (;s[i+f[i]]==s[i-f[i]];) f[i]++;
if (f[i]+i>mx) mx=f[i]+i,id=i;
res+=f[i]>>1,res%=mod;
}
return res;
}

int main(){
POW[0]=1;for (int i=1;i<maxn;i++) POW[i]=(POW[i-1]<<1)%mod;
scanf("%s",str),n=strlen(str);
for (nn=1;nn<(n<<1);nn<<=1);
for (int i=0;i<n;i++) a.a[i].r=(str[i]=='a'?1.0:0.0);
for (int i=0;i<n;i++) b.a[i].r=(str[i]=='b'?1.0:0.0);
a.fft(0,1,nn,1),b.fft(0,1,nn,1);
for (int i=0;i<nn;i++)
a.a[i]=a.a[i]*a.a[i]+b.a[i]*b.a[i];
a.fft(0,1,nn,-1);
for (int i=0;i<nn;i++) a.a[i].r/=nn;
for (int i=0;i<nn;i++){
int x=(int)(round(a.a[i].r)+1)>>1;
ans=(ans+POW[x]-1)%mod;
}
//int t=(int)clock();
printf("%d\n",(ans-manacher()+mod)%mod);//
//printf("%d\n",(int)clock()-t);
return 0;
}



posted @ 2015-07-21 08:17  orzpps  阅读(96)  评论(0编辑  收藏  举报