【怪物】KMP畸形变种——扩展KMP】的更多相关文章

问题 参考51nod1304这道题: 很显然我们要求的是S的每个后缀与S的最长公共前缀的长度之和. 暴力 假设我们把next[i]表示为第i个后缀与S的最长公共前缀的长度. 现在我们想了:这个next数组,如果暴力来求的话,时间复杂度是O(n2). 这是我们回忆一下KMP:KMP物尽其用,然后呢就把求fail的速度提高到了O(n). 那么我们在求next数组的时候,可不可以也使用这样的想法来物尽其用,尽可能地去除重复的匹配呢? 答案是肯定的. 引入扩展KMP 假设要处理出S的next数组,现在已…
http://codeforces.com/blog/entry/3107 // s[0, ..., n-1], z[0] = 0// z[i] is the length of the longest substring starting from s[i] which is also a prefix of s // O(n), R increases... , R = ; ; i < n; i++) { if (i > R) { L = R = i; while (R < n &a…
扩展kmp                 LRH 所谓扩展kmp指的是与kmp相似的求辅助数组的原理,但是本身与kmp关系不大. 1.exkmp的用途:给定一个主串s和一个子串t,求出s中每一个后缀和子串t的最长公共前缀. 2.算法推导: 给定一个主串:S=aaaaaaaaaabaaa  T=aaaaaaaaaaa (下标都是从零开始!!!)                  第一步 需要有两个辅助数组:extand[i]和next[i]: extand[i]:表示主串S以i开始的后缀与子串T…
扩展kmp                 LRH 所谓扩展kmp指的是与kmp相似的求辅助数组的原理,但是本身与kmp关系不大. 1.exkmp的用途:给定一个主串s和一个子串t,求出s中每一个后缀和子串t的最长公共前缀. 2.算法推导: 给定一个主串:S=aaaaaaaaaabaaa  T=aaaaaaaaaaa (下标都是从零开始!!!)                  第一步 需要有两个辅助数组:extand[i]和next[i]: extand[i]:表示主串S以i开始的后缀与子串T…
一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所有的extend[1..n].容易发现,如果存在某个i,使得extend[i] = m,这便是经典的KMP算法要解决的问题. 二 扩展KMP算法思想 和KMP算法的是想类似,充分利用已经比较字符性质来减少冗余的字符比较次数.KMP的思想是充分的利用模式串中所有前缀字串(以模式串为开头的字串)的真前缀…
Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权值(可能为负),你需要将这个字符串分成两个子串,使得这两个子串的价值之和最大.一个子串价值的计算方法:如果这个子串是回文串,那么价值就是这个子串所有字符权值之和:否则价值为0. analyse: 扩展KMP算法运用.总体思路:找出所有包含第一个字母的回文串和包含最后一个字母的回文串,然后O(n)扫一…
文章网上太多这里提一下代码细节: KMP: scanf("%s\n",s); scanf("%s\n",t); int ls=strlen(s),lt=strlen(t); f[]=f[]=; ;i<lt;++i) { int j=f[i]; while(j&&t[j]!=t[i]) j=f[j]; ]=j+;]=; } ; ;i<ls;++i) { while(j&&t[j]!=s[i]) j=f[j]; if(t[j]…
扩展KMP的简单题. #include<stdio.h> #include<string.h> #define maxn 51010 char s[maxn],t[maxn]; int extand[maxn],next[maxn]; void getnext(char *t) { int i,k,j,len=strlen(t); next[]=len; i=; &&t[i]==t[i+]) { i++; } next[]=i; ; ;k<len;k++) {…
慢慢研究可以发现,可以用扩展kmp来求.由于扩展kmp的next[]只有一部分,当前位子前面那部分和母串的后部分,所以可以将字符串复制接在后面一次. 先求如果next[]>0&&next[]!=len,那么只要考虑后面那位的大小比较.如果next[]>=len 那就是相同.如果next[]==0,就是没有相同的,直接比较开头. 这样做还是会超时,我tle无数发. 还要去掉重复的部分,题目要求不同的.所以求出循环部分,只要考虑一部分即可. //扩展kmp求最小循环节 int kk…
刘雅琼论文 http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html 论文讲的非常详细. 给定母串S,子串T,n=strlen(S),m=stlrne(T);extand[i]=S[i...n]与T的最长公共前缀长度,要在线性时间求出所有extand[]. 下面是代码 #define maxn 10010 int extand[maxn],next[maxn]; void getnext(char *t) { int i,j,len=st…