hdu 3336 KMP
Count the string
1 /*
2 写于13年3月21日
3 http://acm.hdu.edu.cn/showproblem.php?pid=3336
4 2013-03-21 10:39:01 Accepted 3336 46MS 2016K
5 很巧妙的利用了KMP函数get_next()的思想
6 通过对其进行改写达到目的
7 data[i]表示[1....i]字符串出现的次数
8 */
9
10 #include <iostream>
11 #include <stdio.h>
12 #include <string.h>
13 using namespace std;
14
15 char s[200005];
16 int next[200005];
17 int data[200005];
18
19 void get_next(int n)
20 {
21 int j=0,i=1;
22 next[1]=0;
23 memset(data,0,sizeof(data));//将data初始化
24 while(i<=n)
25 {
26 if(j==0||s[i]==s[j])
27 {
28 ++data[i];//字符串[1...i]第一次出现时置为1
29
30 ++i;
31 ++j;
32 next[i]=j;
33 /*get_next的优化算法,但此处用不上
34 if(s[i]!=s[j])
35 next[i]=j;
36 else
37 next[i]=next[j];
38
39 */
40 //j>1表示此时有s[i-1]==s[j-1],即有[1...j-1]出现第二次或更多次,j<n
41 if(j>1)
42 data[j-1]++;
43 }
44 else
45 j=next[j];
46 }
47 }
48 int main()
49 {
50 int t;
51 int n;
52 scanf("%d",&t);
53 while(t--)
54 {
55 int ans=0;
56 scanf("%d",&n);
57 /*
58 for(int i=1;i<=n;i++)
59 scanf("%c",&s[i]);
60 此时%c接受空格回车等,就是在这里调试了一晚上,囧!
61 以后要改用c++了!
62 */
63 scanf("%s",s+1);//字符串从s[1]开始
64 get_next(n);
65 for(int i=1;i<=n;i++)
66 {
67 //各个前缀出现的总次数和
68 ans=(ans+data[i])%10007;
69 }
70 ans=(ans)%10007;
71 printf("%d\n",ans);
72 }
73 return 0;
74 }