上个帖子忘放代码了,且沉下去了,重新发一个。
Manacher+FFT,第一个点 WA 了,求大佬相助。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define re register
#define M 1000000007
#define in inline
using namespace std;
int n,mx,p[400005],k,len,fac[400005],Inv[400005],ifac[400005],rev[400005],g[400005],ans;
struct cp{
long double rl,im;
cp operator +(cp y)const{return (cp){rl+y.rl,im+y.im};}
cp operator /(re int x)const{return (cp){rl/x,im/x};}
cp operator -(cp y)const{return (cp){rl-y.rl,im-y.im};}
cp operator *(cp y)const{return (cp){rl*y.rl-im*y.im,rl*y.im+im*y.rl};}
}wi[400005],f[400005];
char s[400005],l[400005];
inline void mns(re int &x,re int y){x-=y<0?x+=M:x;}
inline int make(int n){
int l=ceil(log2(n));n=1<<l;
for(int i=1;i<n;i++)rev[i]=rev[i>>1]>>1|((i&1)<<(l-1));
return n;
}
inline int ksm(int x,int y){
int ans=1;
while(y){
if(y&1)ans=1ll*ans*x%M;
x=1ll*x*x%M,y>>=1;
}
return ans;
}
inline void FFT(re cp* A,re int n,re int f) {
for(re int i=0; i<n; ++i)if(rev[i]<i)swap(A[i],A[rev[i]]);
for(re int i=1; i<n; i<<=1) {
cp wn=(cp){cos(M_PI/i),sin(M_PI/i)*f};
wi[0]=(cp){1,0};
for(re int j=1; j<i; ++j)wi[j]=wi[j-1]*wn;
for(re int j=0; j<n; j+=(i<<1))
for(re int k=0; k<i; ++k) {
cp x=A[j+k],y=A[j+k+i]*wi[k];
A[j+k]=x+y,A[j+k+i]=x-y;
}
}
if(f==-1)for(re int i=0; i<n; ++i)A[i]=A[i]/n;
}
inline void Manacher(){
l[len=mx=k=0]='$',l[++len]='#';
for(re int i=0;i<n;++i){l[++len]=s[i];l[++len]='#';}l[len+1]='\0';
for(re int i=1;i<=len;++i){
if(mx>i)p[i]=min(p[(k<<1)-i],mx-i+1);
else p[i]=1;
while(l[i+p[i]]==l[i-p[i]])++p[i];
if(p[i]+i>mx)mx=p[i]+i-1,k=i;
ans-=p[i]>>1;
}
}
int main(){
scanf("%s",s),n=strlen(s);
k=make(n<<1);
for(re int i=0;i<n;++i)f[i]=(cp){(s[i]=='a'),0};
FFT(f,k,1);for(re int i=0;i<k;++i)f[i]=f[i]*f[i];FFT(f,k,-1);
for(re int i=0;i<k;++i)(g[i]+=f[i].rl+0.5)%=M;
for(re int i=0;i<k;++i)f[i]=(cp){0,0};
for(re int i=0;i<n;++i)f[i]=(cp){(s[i]=='b'),0};
FFT(f,k,1);for(re int i=0;i<k;++i)f[i]=f[i]*f[i];FFT(f,k,-1);
for(re int i=0;i<k;++i)(g[i]+=f[i].rl+0.5)%=M;
for(re int i=0;i<k;++i)(ans+=ksm(2,((g[i]+1)>>1))-1)%=M;
Manacher();ans<0?ans+=M:ans;
printf("%d",ans);
}