题目链接:【hdu 3336】
t组测试数据,输入长为n的字符串s[n](1<=n<=200000),求s[]的每一个前缀在s[]中出现的总次数
例如:s[] = ababa
前缀 次数
a 3
ab 2
aba 2
abab 1
ababa 1
====> 输出9
先用KMP求出数组f[n],对于ababa,相应的f[n] = {0,0,1,2,3}
f[i] = x ===> s[1~x]与s[x~i]完全相等,那么到x为止,在s[1~x]出现过的以s[x]为结尾的前缀一定会在s[x~i]中
例如:s[] = ababa(我们就专注于结尾是a的,结尾是b的先不用去管它)
图中字符串下面的红线表示的是到i为止,出现的以s[i]为结尾的前缀
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define mod 10007
#define inf 200100
char s[inf];
int t, n, f[inf], dp[inf], ans;
void getf()
{
memset(f, 0, sizeof(f));
int j=0;
for(int i=2; i<=n; i++)
{
while(j&&s[i]!=s[j+1]) j = f[j];
f[i] = (s[i]==s[j+1] ? ++j:0);
}
}
int main()
{
scanf("%d", &t);
while(t--)
{
memset(dp, 0, sizeof(dp));
ans = 0;
scanf("%d%s", &n, s+1);
getf();
for(int i=1; i<=n; i++)
{
dp[i] = (dp[f[i]]+1) % mod;
ans = (ans+dp[i]) % mod;
}
printf("%d\n", ans);
}
return 0;
}