hdu3336 kmp

题意:求前缀个数和,前缀是字符串的所有前缀。

eg:1
      4
      abab
a:2个    ab:2个   aba:1个   abab:1个  共6个

思路:
字符串: a  b  a  b
next[i]:0  0  1  2

字符串: a  b  c  a  b  a  b  c   a  b  c  a  b  c   a  b
next[i]:0  0  0 1  2  1  2  3  4  5  3  4  5  3  4  5

                  -1,i=0;
next[i]=  Max{k|0<k<i,其中 ‘0~k-1’ 与 ‘i-k+1~i-1’ 相匹配};
                  0,其他;

所以要想求长度为j前缀有多少个,只需要看next[i]=j的有多少个就可以了,但是例如最后的ab的next值为45,而不是12
因为next[i]存的是最长的匹配长度,所以dp[i]=dp[next[i]]+1;

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 const int N=200010;
 4 const int mod=10007;
 5 char s[N];
 6 int next[N],len;
 7 void getNext(){
 8     int i=0,j=-1;
 9     next[0]=-1;
10     while(i<len){
11         if(j==-1||s[i]==s[j]){
12             i++;j++;
13             next[i]=j;
14         }
15         else j=next[j];
16     }
17 }
18 int main(){
19     int t,i;
20     scanf("%d",&t);
21     while(t--){
22         scanf("%d",&len);
23         scanf("%s",s);
24         getNext();
25         int res=0,pos;
26         for(i=1;i<=len;i++){
27             pos=i;
28             while(pos){
29                 res=(res+1)%mod;
30                 pos=next[pos];
31             }
32         }
33         printf("%d\n",res);
34     }
35     return 0;
36 }

 

posted @ 2013-02-09 03:41  _sunshine  阅读(327)  评论(0编辑  收藏  举报