给了两条限制,但是第二条想想是没用的,直接manacher就可以减掉多余的部分了,所以要求满足第一条的方案
也不难,可以想到枚举每个中心点,计算两边有多少对距离中心相等的位置值也相等,假设有(t)个,那么以这个中心点为半径的就是(2^t-1),因为每个都可以选或不选,减去全都不选的情况
现在就要计算和每个中心点距离相等的位置对数了,显然两个位置(a,b)如果值相同,那么中心就是((a+b)/2)(如果是小数的话就是两个格子之间的)
所以就简单了,(A(i)=[S[i]='a'],B(i)=[S[i]='b']),这两个多项式分别平方一下,然后再算(2^x-1),所有这些之和就是满足第一条的方案了
#include<bits/stdc++.h>
#define il inline
#define vd void
#define mod 1000000007
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
const double pi=acos(-1);
struct cp{
double real,imag;
cp(){}
cp(const double&r,const double&i){real=r,imag=i;}
il cp conj(){return(cp){real,-imag};}
il vd operator =(const double&b){real=b,imag=0;}
};
il cp operator +(const cp&a,const cp&b){return(cp){a.real+b.real,a.imag+b.imag};}
il cp operator -(const cp&a,const cp&b){return(cp){a.real-b.real,a.imag-b.imag};}
il cp operator *(const cp&a,const cp&b){return(cp){a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real};}
char S[200010];
int rev[1<<19];
cp A[1<<19],omg[1<<19],inv[1<<19];
il vd fft(cp*A,int n,cp*omg){
for(int i=0;i<n;++i)if(rev[i]>i)std::swap(A[i],A[rev[i]]);
for(int o=1;o<n;o<<=1)
for(cp*p=A;p!=A+n;p+=o<<1)
for(int i=0;i<o;++i){
cp t=omg[n/(o<<1)*i]*p[i+o];
p[i+o]=p[i]-t,p[i]=p[i]+t;
}
}
int t[200010];
il int pow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}
return ret;
}
int r[200010];
int main(){
scanf("%s",S+1);int n=strlen(S+1);
int N=1,lg=0;while(N<(n+2)<<1)N<<=1,++lg;
for(int i=0;i<N;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
for(int i=0;i<N;++i)omg[i]=cp(cos(i*2*pi/N),sin(i*2*pi/N)),inv[i]=omg[i].conj();
for(int i=1;i<=n;++i)A[i]=S[i]=='a';
fft(A,N,omg);
for(int i=0;i<N;++i)A[i]=A[i]*A[i];
fft(A,N,inv);
for(int i=1;i<=n<<1;++i)t[i]=(int)(A[i].real/N+0.5);
for(int i=0;i<N;++i)A[i]=0;
for(int i=1;i<=n;++i)A[i]=S[i]=='b';
fft(A,N,omg);
for(int i=0;i<N;++i)A[i]=A[i]*A[i];
fft(A,N,inv);
for(int i=1;i<=n<<1;++i)t[i]+=(int)(A[i].real/N+0.5);
ll ans=0;
for(int i=1;i<=n<<1;++i)t[i]=t[i]/2+!(i&1),ans+=pow(2,t[i])-1;
for(int i=n;i;--i)S[i<<1]=S[i];
N=n<<1|1;
for(int i=1;i<=N;i+=2)S[i]='#';
S[0]='s',S[N+1]='t';
int R=1,mid=1;r[1]=1;
for(int i=2;i<=N;++i){
r[i]=1;
if(i<=R)r[i]=std::min(R-i+1,r[mid*2-i]);
while(S[i-r[i]]==S[i+r[i]])++r[i];
if(i+r[i]-1>R)mid=i,R=i+r[i]-1;
}
for(int i=1;i<=N;++i)ans-=r[i]>>1;
printf("%lld
",(ans%mod+mod)%mod);
return 0;
}