# Luogu P4199 万径人踪灭

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define R register int
#define ll long long
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
} const int N=400010,M=1000000007;
const double PI=acos(-1.0);
int n,p[N],K,len,f[N],ans;
char s[N];
struct ci {
double x,y;
inline ci operator + (const ci& that) const
{return (ci){x+that.x,y+that.y};}
inline ci operator - (const ci& that) const
{return (ci){x-that.x,y-that.y};}
inline ci operator * (const ci& that) const
{return (ci){x*that.x-y*that.y,x*that.y+y*that.x};}
}a[N];
inline void fft(ci* a,int op) {
for(R i=0;i<K;++i) if(i<p[i]) swap(a[i],a[p[i]]);
for(R l=1;l<K;l<<=1) {
register ci w1=(ci){cos(PI/l),op*sin(PI/l)},wn,x,y;
for(R len=l<<1,i=0;i<K;i+=len) {
wn=(ci){1,0};
for(R j=0;j<l;++j,wn=wn*w1)
x=a[i+j],y=wn*a[i+j+l],a[i+j]=x+y,a[i+j+l]=x-y;
}
}
}
struct PAM {
int lst,tot,fa[N],len[N],c[N][26],sz[N]; ll ans;
inline void init() {len[fa[0]=tot=1]=-1;}
inline int jmp(int p,int i)
{while(s[i-len[p]-1]!=s[i]) p=fa[p]; return p;}
inline void ext(int ch,int i) {
R p=jmp(lst,i); if(!c[p][ch]) {
R np=++tot; len[np]=len[p]+2;
R t=jmp(fa[p],i);
fa[np]=c[t][ch],c[p][ch]=np;
} ++sz[lst=c[p][ch]];
}
inline void cal() {
for(R i=tot;i>=2;--i)
sz[fa[i]]+=sz[i],ans+=sz[i];
}
}p1;
inline int qpow(int a,int b) { R ret=1;
for(;b;b>>=1,a=1ll*a*a%M) if(b&1) ret=1ll*ret*a%M; return ret;
}
inline void main() {
scanf("%s",s+1),n=strlen(s+1),p1.init();
for(R i=1;i<=n;++i) p1.ext(s[i]-'a',i);
K=1; while(K<=2*n) K<<=1,++len;
for(R i=0;i<K;++i) p[i]=(p[i>>1]>>1)|((i&1)<<(len-1));
for(R i=1;i<=n;++i) a[i].x=s[i]=='a',a[i].y=0;
fft(a,1); for(R i=0;i<K;++i) a[i]=a[i]*a[i];
fft(a,-1); for(R i=0;i<K;++i) f[i]=(f[i]+(int)(a[i].x/K+0.5))%M;
memset(a,0,sizeof a);
for(R i=1;i<=n;++i) a[i].x=s[i]=='b',a[i].y=0;
fft(a,1); for(R i=0;i<K;++i) a[i]=a[i]*a[i];
fft(a,-1); for(R i=0;i<K;++i) f[i]=(f[i]+(int)(a[i].x/K+0.5))%M;
p1.cal(); ans=-p1.ans%M;
for(R i=1;i<=2*n;++i) ans=(ans+qpow(2,f[i]/2+((i&1)^1))-1)%M;
printf("%d\n",(ans+M)%M);
}
} signed main() {Luitaryi::main(); return 0;}


2020.01.16

posted @ 2020-01-16 20:44  LuitaryiJack  阅读(132)  评论(0编辑  收藏  举报