标签:algo ane ext sample efi cal else rac class
InputThe first line is a single integer T, indicating the number of test cases.
For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.
OutputFor each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.Sample Input
1 4 abab
Sample Output
6
一个结论:cnt[i] 表示 因为加入i字符而增加的 以i字符结束的前缀数目
cnt[i] = cnt[Next[i]] + 1
Next[]数组表示前j个字符中最长的相同前缀后缀长度
证明:
如果Next[i]==0 也就是说 i字符没有在之前出现过,那么因为加入字符i增加的前缀只有0-i这个字符串
否则 增加的数目要考虑由于第i-k个字符到第i个字符组成的字符串是前缀的情况,增加的数目为这种前缀的数目+1,那么这种前缀的数目如何求?
显然,考虑i之前最长匹配的前缀后缀,在最长匹配处加入字符i增加的前缀 等于 在i处加入字符i增加的前缀
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include <sstream> #include<string> #include<cstring> #include<list> using namespace std; #define MAXN 200002 #define INF 0x3f3f3f3f #define M 10007 typedef long long LL; /* 输出字符串中所有前缀在字符串中出现的次数 ababab */ char t[MAXN]; int Next[MAXN],cnt[MAXN]; void kmp_pre(char t[]) { int m = strlen(t); int j,k; j = 0;k = Next[0] = -1; while(j<m) { if(k==-1||t[j]==t[k]) Next[++j] = ++k; else k = Next[k]; } } int main() { int T; scanf("%d",&T); while(T--) { int l,ans=0; scanf("%d",&l); scanf("%s",t); kmp_pre(t); for(int i=1;i<=l;i++) { cnt[i] = (cnt[Next[i]]+1); ans = (ans+cnt[i])%M; } printf("%d\n",ans); } }
标签:algo ane ext sample efi cal else rac class
原文地址:http://www.cnblogs.com/joeylee97/p/6681223.html