Hdu 3336 Count the string[KMP next数组的理解]
来源:互联网 发布:设计师必知的100 编辑:程序博客网 时间:2024/06/05 04:28
题意:求字串中【前缀+跟前缀相同的子串】的个数?
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个
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。
到这里,有些同学就要问了,为什么next[4]为什么就不做处理了呢??
我一开始也是这么想的,为什么呢??
因为,next[4]的后面的next[5]==(正好)next[4]+1。这不是偶然,因为abca的最大后缀为1(a),而abcab的最大后缀为2(ab),这里的ab包含了前面的a。所以,如果正好next[i]+1=next[i]的话,前面的被后面包含了。
代码:
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int N=200003;char Str[N];int n,next[N];void Get_Next(){ next[0]=-1; int j=-1,i=0; while(i<n){ if(j==-1||Str[i]==Str[j]){ j++;i++; next[i]=j; } else j=next[j]; }}int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d",&n); scanf("%s",Str); Get_Next(); int ans=n+next[n]; for(int i=0;i<n;i++){ if(next[i]>0&&next[i]+1!=next[i+1]) ans=(ans+next[i])%10007; } printf("%d\n",ans); } return 0;}
由此可见,KMP的next数组的博大精深呐!!
0 0
- Hdu 3336 Count the string[KMP next数组的理解]
- [KMP-NEXT数组特性]HDU 3336 Count the string
- 【HDU 3336】Count the string 【KMP next数组巧妙应用】
- HDU 3336 Count the string(KMP算法next数组的应用)
- HDU 3336 Count the string(KMP+稍微DP+next数组的运用)
- HDU 3336 Count the string(kmp next数组的性质)
- HDU3336-Count the string-KMP(next数组理解)
- HDU 3336 Count the string(KMP 理解)
- Count the string kmp next数组应用
- HGU3336 Count the string (KMP Next数组的应用)
- Count the string (kmp的next数组运用)
- HDU 3336 Count the string(KMP+Next数组递推)
- HDU 3336 Count the string (KMP的nex数组)
- HDU 3336 Count the string (next数组活用)
- HDU 3336 Count the string(next数组+DP)
- hdu 3336 Count the string(next数组+dp)
- HDU 3336 Count the string 后缀数组 或 (KMP + DP)
- HDU3336 Count the string(KMP,next的性质)
- jsp通过url传递和获取参数
- Java 单例模式详解
- 控制器方法(Controller Methods),接着上面继续说哈!
- C++中的修饰符 mutable
- 揭秘在ListView等AdapterView上动态添加删除项的陷阱
- Hdu 3336 Count the string[KMP next数组的理解]
- DNN摸索系列3:DNN 6 安装永日新闻模块
- 让你精力充沛的25个简单方法
- 以前编写的inno setup脚本,涵盖了自定义安装界面,调用dll等等应用
- win8.1 断网解决方案
- Struts2常用标签总结
- TI辅助工具:开关电源设计精灵
- [转载]INNO SETUP注册DLL文件
- jsp的字符串比较