码迷,mamicode.com
首页 > 编程语言 > 详细

hdu 3336 kmp+next数组应用

时间:2015-03-12 11:26:05      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:

分析转自:http://972169909-qq-com.iteye.com/blog/1114968

十分易懂

题意:求字串中【前缀+跟前缀相同的子串】的个数?

Sample Input
1
4
abab

Sample Output
6

abab:包括2个a,2个ab,1个aba,1个abab

这里要用到next值的意义:
next[i]表示前i个字符所组成的字符串的最大前后缀匹配长度
举个例子:
技术分享
next[5]=2, 表示下标5前面那个字符串abcab的前后缀匹配的最大长度是2,显然就是ab了

回到本题:
所求=字串的前缀个数+与前缀相同的子串
问题可以部分转化为:每个前缀的最大前后缀匹配问题

继续用上面的例子:

第一步:
技术分享
对于这段子串,next[5]=2,然后后面不符合next值的递推规律了
所以对于abcab,长度为2的后缀,即ab与前缀匹配
所以+1个ab,注意还要+1个a,既然后缀ab跟前缀ab匹配,则必有a跟前缀匹配
也就是+2个了,其实实际上+next[5]就可以了,因为这是最长前后缀匹配长度

第二步:
技术分享
对于这段子串:
next[6]=1,然后后面不符合next值的递推规律了
所以对于abcaba,长度为1的后缀,即a与前缀匹配
所以+1个a,也就是+next[6]了

第三步:
技术分享
对于整个串:
next[12]=4后面没有了
所以对于整个串:abcabacbabca,长度为4的后缀跟前缀匹配
所以+1个abca,+1个abc,+1个ab,+1个a,总共+4个,也就是+next[12]了

最后:
好了,刚刚一共+了7个与前缀匹配的子串
上面说了题目是求:字串的前缀个数+与前缀相同的子串个数
与前缀相同的子串个数就是7个了
然后字串的前缀个数当然就是整个串的长度了,那么就是12个
加起来就是答案:19

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 const int MAXN=200020;
 4 const int MOD=10007;
 5 int dp[MAXN];
 6 char str[MAXN];
 7 int next[MAXN];
 8 
 9 void getNext(char *p)
10 {
11     int j,k;
12     j=0;
13     k=-1;
14     next[0]=-1;
15     int len=strlen(p);
16     while(j<len)
17     {
18         if(k==-1||p[j]==p[k])
19         {
20             j++;
21             k++;
22             next[j]=k;
23         }
24         else k=next[k];
25     }
26 }
27 int main()
28 {
29     int T;
30     int n;
31     scanf("%d",&T);
32     while(T--)
33     {
34         scanf("%d",&n);
35         scanf("%s",&str);
36         getNext(str);
37         dp[0]=0;
38         int ans=0;
39         for(int i=1;i<=n;i++)
40         {
41             dp[i]=dp[next[i]]+1;
42             dp[i]%=MOD;
43             ans+=dp[i];
44             ans%=MOD;
45         }
46         printf("%d\n",ans);
47     }
48     return 0;
49 }

 

hdu 3336 kmp+next数组应用

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4331759.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!