http://uoj.ac/problem/5 (题目链接)
题意
求字符串各个前缀的前缀与后缀相同但不重叠的子串的个数+1之积
Solution
KMP。第一遍求next和符合条件的可以重叠的子串。第二遍,求符合条件的不重叠的子串,注意此时不可以重新求next,直接使用上次求出来的next。
代码
// uoj5
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf (1ll<<30)
#define MOD 1000000007
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
const int maxn=1000010;
int next[maxn],num[maxn],sum[maxn];
char s[maxn];
int main() {
int T;scanf("%d",&T);
while (T--) {
scanf("%s",s+1);
int n=strlen(s+1);
next[1]=0;sum[0]=-1;num[0]=-1;
for (int j=0,i=2;i<=n;i++) {
while (j && s[j+1]!=s[i]) j=next[j];
if (s[j+1]==s[i]) j++;
next[i]=j;sum[i]=sum[j]+1;
}
for (int j=0,i=2;i<=n;i++) {
while (j && (s[j+1]!=s[i] || j+1>i/2)) j=next[j];
if (s[j+1]==s[i]) j++;
num[i]=sum[j]+1;
}
LL ans=1;
for (int i=1;i<=n;i++) ans=ans*(num[i]+1)%MOD;
printf("%lld\n",ans);
}
return 0;
}