您的位置:首页 > 其它

[BZOJ3160]万径人踪灭(FFT+Manacher)

2018-07-11 19:54 309 查看

https://www.geek-share.com/detail/2733332600.html

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std;

const int N=400010,mod=1e9+7;
const double pi=acos(-1.);
int n,len,ans,L,mx,id,bin
,rev
,f
,p
;
char s
,tmp
;

struct C{
double x,y;
C(double _x=0,double _y=0):x(_x),y(_y){}
C operator +(C &b){ return C(x+b.x,y+b.y); }
C operator -(C &b){ return C(x-b.x,y-b.y); }
C operator *(C &b){ return C(x*b.x-y*b.y,x*b.y+b.x*y); }
}a
;

void FFT(C a[],int f){
for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=1; i<n; i<<=1){
C wn=C(cos(pi/i),f*sin(pi/i));
for (int p=i<<1,j=0; j<n; j+=p){
C w(1,0);
for (int k=0; k<i; k++,w=w*wn){
C x=a[j+k],y=w*a[i+j+k]; a[j+k]=x+y; a[i+j+k]=x-y;
}
}
}
if (f==-1) for (int i=0; i<n; i++) a[i].x/=n;
}

void work(char ch){
for (int i=0; i<n; i++) a[i]=C(s[i]==ch,0);
FFT(a,1); for (int i=0; i<n; i++) a[i]=a[i]*a[i]; FFT(a,-1);
rep(i,2,len<<1) f[i]+=((int)(a[i].x+0.5)+1)/2;
}

int main(){
freopen("bzoj3160.in","r",stdin);
freopen("bzoj3160.out","w",stdout);
scanf("%s",s+1); len=strlen(s+1);
bin[0]=1; rep(i,1,len) bin[i]=(bin[i-1]<<1)%mod;
for (n=1; n<=(len<<1); n<<=1) ++L;
for (int i=0; i<n; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
work('a'); work('b');
rep(i,2,len<<1) ans=(ans+bin[f[i]]-1)%mod;
rep(i,1,len) tmp[i]=s[i];
s[0]='$'; s[1]='#';
rep(i,1,len) s[i<<1]=tmp[i],s[(i<<1)|1]='#';
rep(i,1,len<<1){
p[i]=(mx>i) ? min(p[2*id-i],mx-i) : 1;
while (s[i-p[i]]==s[i+p[i]]) p[i]++;
if (i+p[i]>mx) mx=i+p[i],id=i;
}
rep(i,1,len<<1) ans=(ans-p[i]/2+mod)%mod;
printf("%d\n",ans);
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: