题解:
这是一道神题,具体题解直接看官方的比较好…
用到了策爷字符串ppt中回文串的回文后缀是
logn
log
n
个等差数列的性质。
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+50;
const int mod=1e9+7;
int n,f[N],tot=1;
char s[N],t[N];
int last,son[N][27],diff[N],len[N],link[N],slink[N],series_ans[N];
inline int getfail(int pos,int l) {
while(s[l-len[pos]-1]!=s[l]) pos=link[pos];
return pos;
}
int main() {
len[1]=-1; link[0]=1; diff[0]=1;
scanf("%s",t+1); n=strlen(t+1);
if(n&1) {puts("0"); return 0;}
for(int i=1;i<=n;i++) {
if(i&1) s[i]=t[(i+1)/2];
else s[i]=t[n-i/2+1];
}
f[0]=1;
for(int i=1;i<=n;i++) {
int c=s[i]-'a'+1;
int now=getfail(last,i);
if(!son[now][c]) {
len[++tot]=len[now]+2;
link[tot]=son[getfail(link[now],i)][c];
diff[tot]=len[tot]-len[link[tot]];
if(diff[tot]==diff[link[tot]]) slink[tot]=slink[link[tot]];
else slink[tot]=link[tot];
son[now][c]=tot;
} last=son[now][c];
for(int v=last;len[v];v=slink[v]) {
series_ans[v]=f[i-(len[slink[v]]+diff[v])];
if(diff[v]==diff[link[v]])
series_ans[v]=(series_ans[v]+series_ans[link[v]])%mod;
f[i]=(f[i]+series_ans[v])%mod;
}
if(i&1) f[i]=0;
}
printf("%d\n",f[n]);
}