NOI2014 动物园
题目连接:戳我
就是......KMP算法的nxt数组表示的是能和它配对的,右端字符最靠右的,字符串的位置。所以我们一个一个向前跳,当此时的j的位置*2小于等于i的时候,就是不重叠的配对子串了。但是一个一个跳跑的有一点慢......所以我们可以上一个倍增数组........
然后开个O2就过去了。。。。
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 1000010
#define MOD 1000000007
#define ull unsigned long long
using namespace std;
int T,len,ans;
int nxt[MAXN],fp[22][MAXN];
char s[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&T);
while(T--)
{
ans=1;
memset(nxt,0,sizeof(nxt));
scanf("%s",s+1);
len=strlen(s+1);
int p=0;
for(int i=2;i<=len;i++)
{
while(p&&s[p+1]!=s[i]) p=nxt[p];
if(s[p+1]==s[i]) p++;
nxt[i]=p;
}
for(int i=2;i<=len;i++) fp[0][i]=nxt[i];
for(int k=1;k<=21;k++)
for(int i=2;i<=len;i++)
fp[k][i]=fp[k-1][fp[k-1][i]];
for(int i=2;i<=len;i++)
{
int now=i;
for(int j=21;j>=0;j--)
if(fp[j][now]*2>i)
now=fp[j][now];
int cur_ans=0;
for(int j=21;j>=0;j--)
if(fp[j][now])
cur_ans+=(1<<j),now=fp[j][now];
ans=1ll*ans*(cur_ans+1)%MOD;
}
printf("%d\n",ans);
}
return 0;
}