企鹅太可爱啦!
题解
我们先处理出num[i]表示既是它的后缀同时又是它的前缀,并且该后缀与该前缀不重叠,这种字符串的数量。每次num[i]=num[fail[i]]+1(因为本身也算一个后缀)。然后再将算出p < i/2并且s[p]=s[i]这种情况,+1乘在答案中即可。详见代码。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define mod 1000000007
#define N 1000010
using namespace std;
char s[N];
int fail[N],num[N],T;
int main()
{
for (scanf("%d\n",&T);T;T--)
{
gets(s+1),num[1]=1;int ans=1,j=0,p=0,mid;
for (int i=2;s[i];i++)
{
for (;j&&s[j+1]!=s[i];j=fail[j]);
if (s[i]==s[j+1]) j++;
num[i]=num[fail[i]=j]+1;mid=i>>1;
for (;p&&(p+1>mid||s[i]!=s[p+1]);p=fail[p]);
if (s[i]==s[p+1]) p++;
ans=(ll)ans*(num[p]+1)%mod;
}
printf("%d\n",ans);
}
return 0;
}