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