HDU 3336 Count the String(KMP+DP)
http://acm.hdu.edu.cn/showproblem.php?pid=3336
题意:给出一个字符串,计算所有前缀在字符串中出现的次数。
思路:考虑KMP的next[]来解题。next[i]=j表示最大的j使得0~j==i-j~i。
对于样例的next[]分析如下:
0 1 2 3
a[] a b a b
next[] -1 0 0 1
dp[i]表示子串a[0~i]共含有以a[i]为结尾的前缀的数目,则以a[i]结尾的前缀数就是自己本身加上以a[next[i]]结尾的前缀数,即dp[next[i]]。
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 const int maxn = 200000 + 5; 6 7 int n; 8 9 char a[maxn]; 10 int next[maxn]; 11 int dp[maxn]; 12 13 void get_next() 14 { 15 int i = -1, j = 0; 16 ::next[0] = -1; 17 int l = strlen(a); 18 while (j < l) 19 { 20 if (i == -1 || a[i] == a[j]) 21 ::next[++j] = ++i; 22 else 23 i = ::next[i]; 24 } 25 } 26 27 int main() 28 { 29 //freopen("D:\\txt.txt", "r", stdin); 30 int t; 31 cin >> t; 32 while (t--) 33 { 34 cin >> n; 35 cin >> a; 36 get_next(); 37 memset(dp, 1, sizeof(dp)); 38 dp[0] = 0; 39 int sum = 0; 40 for (int i = 1; i <= n; i++) 41 { 42 dp[i] = dp[::next[i]] + 1; 43 sum += dp[i] % 10007; 44 } 45 cout << sum % 10007 << endl; 46 } 47 return 0; 48 }