题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3336
题意:给你一个字符串,计算其所有前缀在该字符串出现的次数的总和。
思路:next[j]=i,代表s[1...i]==s[j-i+1....j],设f[i]表示以s[i]结尾的子串总共含前缀的数量,f[j]=f[i]+1,即以i结尾的子串中含前缀的数量加上前j个字符这一前缀。
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int MOD=10007;
const int MAX=200005;
char s[MAX];
int next[MAX],n,f[MAX];
void getNext(char s[],int len,int next[])
{
next[0]=-1;
int i=0,j=-1;
while(i<len)
{
if(j==-1||s[i]==s[j]) next[++i]=++j;
else j=next[j];
}
}
int C;
int DP()
{
int i,ans=0;
for(i=1;i<=n;i++)
{
f[i]=f[next[i]]+1;
ans=(ans+f[i])%MOD;
}
return ans;
}
int main()
{
for(scanf("%d",&C);C--;)
{
scanf("%d",&n);
scanf("%s",s);
getNext(s,n,next);
printf("%d\n",DP());
}
return 0;
}