大爷题解:BZOJ 3160 万径人踪灭
讲道理的话思路我是想到了的……然后不会manacher就现学了一发。
记得有些奇奇怪怪的地方要用long long!
#include "set"
#include "map"
#include "math.h"
#include "vector"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "iostream"
#include "algorithm"
#define rep(f,a,b) for(f=a;f<=b;f++)
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const int MOD = 1000000007;
const int N = 300005;
struct Complex{
double r,i; typedef Complex ttp;
typedef const ttp ctp; Complex(){r=i=0.0;}
Complex(double _r,double _i){ r=_r; i=_i;}
ttp operator+(ctp&a){return ttp(r+a.r,i+a.i);}
ttp operator-(ctp&a){return ttp(r-a.r,i-a.i);}
ttp operator*(ctp&a){return ttp(r*a.r-i*a.i,r*a.i+i*a.r);}
} ;
typedef Complex V;
template <class __Type>
inline void Rader (__Type a[],int len){
int i,j=len>>1,k;
for (i=1;i<len-1;i++){
if(i<j)swap(a[i],a[j]); k=len;
while(j>=(k>>=1)) j-=k;
if(j<k)j+=k;
}
}
inline void FFT(V a[],int len,int ty){
Rader(a,len); int l,i,j,k; V u,t;
for(l=2;l<=len;l<<=1){ i=l>>1;
V wn(cos(-2*PI*ty/l),sin(-2*PI*ty/l));
for(j=0;j<len;j+=l){
V w(1.0,0.0);
for(k=j;k<i+j;k++){
u=a[k]; t=w*a[i+k];
a[k]=u+t; a[i+k]=u-t;
w=w*wn;
}
}
}
if(ty==-1){
for(i=0;i<len;i++){
a[i].r/=len;
}
}
}
void Self_Convol_FFT(V a[],int len){
FFT(a,len,1); int i;
rep(i,0,len) a[i]=a[i]*a[i];
FFT(a,len,-1);
}
char s[N];
int l,len,power[N];
V a[3*N],b[3*N];
char str[2*N];
int rl[2*N];
int manacher(char*s,int l){
const int n=2*l+1;
int pos=0,rpos=0,sum=0,i;
str[0]='@'; str[n+1]='$';
for(i=1;i<=n;i++){
if(i%2) str[i]='#';
else str[i]=s[i>>1];
} for(i=1;i<=n;i++){
if(rpos>i) rl[i]=min(rl[2*pos-i],rpos-i); else rl[i]=1;
while(str[i-rl[i]]==str[i+rl[i]]) rl[i]++;
if(rl[i]+i>rpos) rpos=rl[i]+i,pos=i;
} for(i=1;i<=n;i++) sum=(sum+(rl[i]>>1))%MOD;
return sum;
}
void work(){ power[0]=1;
for(int i=1;i<=l;i++){
if(s[i]=='a') a[i].r=1.0;
else if(s[i]=='b') b[i].r=1.0;
} len=1; int ans=0;
while((len>>1)<=l)len<<=1;
for(int i=1;i<=len;i++){
power[i]=(power[i-1]<<1)%MOD;
} Self_Convol_FFT(a,len);
Self_Convol_FFT(b,len);
for(int i=1;i<=len;i++){
int t1=(int)(a[i].r+.5),t2=(int)(b[i].r+.5);
ans=(ans+power[(t1+t2+1)>>1]-1)%MOD;
} int extra=manacher(s,l);
printf("%d\n",(ans-extra+MOD)%MOD);
}
int main(){
scanf("%s",s+1);
l=strlen(s+1);
work();
return 0;
}