您的位置:首页 > 其它

【bzoj3160】万径人踪灭 FFT

2016-06-01 21:36 357 查看
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3160

我是一个傻叉 微笑脸

#include<bits/stdc++.h>
#define inf 1000000000
#define ll long long
#define N 200005
#define mod 1000000007
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct CD{
double x,y;
CD(double a=0,double b=0){x=a;y=b;}
friend CD operator + (CD n1,CD n2){return CD(n1.x+n2.x,n1.y+n2.y);}
friend CD operator - (CD n1,CD n2){return CD(n1.x-n2.x,n1.y-n2.y);}
friend CD operator * (CD n1,CD n2){return CD(n1.x*n2.x-n1.y*n2.y,n1.x*n2.y+n1.y*n2.x);}
};
const double Pi=acos(-1.0);
int bit,n,nn,ans,m,mx,id,p[N<<1];
char s
,st[N<<1];
CD a[N<<1],b[N<<1];
void FFT(CD *a,int n,int type){
for(int i=0,j=0;i<n;i++) {
if(j>i)swap(a[i],a[j]);
int k=n;
while(j&(k >>= 1))j&=~k;
j|=k;
}
for(int i=1;i<=bit;i++){
CD w_n(cos(2*type*Pi/(1<<i)),sin(2*type*Pi/(1<<i)));
for(int j=0;j<n;j+=(1<<i)){
CD w(1,0);
for(int k=j;k<j+(1<<(i-1));k++){
CD tmp=a[k],tt=w*a[k+(1<<(i-1))];
a[k]=tmp+tt;
a[k+(1<<(i-1))]=tmp-tt;
w=w*w_n;
}
}
}
if(type<0)for(int i=0;i<n;i++)a[i].x/=n;
}
int main(){
scanf("%s",s);
n=strlen(s);nn=n;
bit=1;
while((1<<bit)<(n<<1))bit++;
n=1<<bit;
for(int i=nn;i<n;i++)a[i]=b[i]=CD(0,0);
for(int i=0;i<nn;i++)if(s[i]=='a')a[i]=CD(1,0);
FFT(a,n,1);
for(int i=0;i<n;i++)a[i]=a[i]*a[i];
FFT(a,n,-1);

for(int i=0;i<nn;i++)if(s[i]=='b')b[i]=CD(1,0);
FFT(b,n,1);
for(int i=0;i<n;i++)b[i]=b[i]*b[i];
FFT(b,n,-1);

for(int i=0;i<n;i++){
int x=round(a[i].x+b[i].x);
x=(x+1)/2;
ans=(ans+(1<<x)-1)%mod;
}

m=nn<<1|1;
for(int i=0;i<nn;i++)st[(i+1)<<1]=s[i];
mx=id=0;
for(int i=1;i<=m;i++){
if(mx>i)p[i]=min(p[2*id-i],mx-i);else p[i]=0;
while(i-p[i]-1>0&&i+p[i]+1<=m&&st[i-p[i]-1]==st[i+p[i]+1])p[i]++;
if(i+p[i]>mx)mx=i+p[i],id=i;
ans=((ans-(p[i]+1)/2)%mod+mod)%mod;
}
printf("%d\n",ans);
return 0;
}


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