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 }