EXKMP
(我和lesphere,reverse研究了这个东西一上午)QAQ
kmp是求字符串S的任意前缀与字符串T的最长的相同的前缀和后缀
exkmp第求字符串S的任意后缀与字符串T的最长公共前缀
与kmp相同,我们先来看S与S自己匹配,也就是求S得任意后缀与S的最长公共前缀pre[]数组
假设我们已经得到了k之前的所有答案:pre[0~k-1] 和 k之前使得i+pre[i]最大的点a(也就是能够延伸到最远的点)
如果a+pre[a]-1(延伸最远的位置)<k(不包含k)那么就暴力往后找就对了
如图是当a+pre[a]-1能包含k的情况:

显然s[0~pre[a]-1]==s[a~a+pre[a]-1]两个矩形是完全相同的(并且s[pre[a]+1]!=s[a+pre[a]]);
而且k在前面矩形中对应点k-a
那么现在有三种情况:
(1):pre[k-a]+k-a-1<pre[a]-1;
也就是说k-a延伸出去也不会超过pre[a]-1的矩形右边界假设l=pre[k-a];
换句话说就是s[l]!=s[k-a+l];
又因为两个矩形完全相同,所以pre[k]不会再在s[k+l]之后匹配上(延伸),所以pre[k]=l=pre[k-a];直接赋值就好;

(2):pre[k-a]+k-a-1>pre[a]-1;
与情况1相反,l=pre[k-a]延伸出了矩形右边框:
如图,两个矩形右边框的右边的那个点不同(s[pre[a]+1]!=s[a+pre[a]]);
又因为左边两个l完全相同,所以s[pre[a]+1]==s[pre[a]-(k-a)](图中左边上面箭头(标有相同))
所以右边矩形后面第一个点s[p+1]!=s[pre[a]-(k-a)],所以pre[k]必定等于l在矩形中的部分长度,所以直接赋值就好;

(3):pre[k-a]+k-a-1==pre[a]-1;
也就是说pre[k-a]刚好等于左边矩形右边框;
如图,由于s[pre[i]+i]!=s[pre[i]]的限制,导致两个不同,而下面的箭头就不能确定了;
于是我们对于这样的情况,就只有从右矩形边框暴力往后找了;

这样所有情况就讨论完了,递推即可
下面给出代码:
void getpre(char *s)
{
int len=strlen(s),a=;
pre[]=len;
while(a<len-&&s[a]==s[a+])a++;
pre[]=a;
a=;
re(k,,len-)
{
int p=a+pre[a]-,l=pre[k-a];
if(k-+l>=p)
{
int j=(p-k+)>?(p-k+):;
while(k+j<len&&s[k+j]==s[j])j++;
pre[k]=j;
a=k;
}
else pre[k]=l;
}
}
S与自身的匹配和S与T的匹配类似,下面给出代码:
void getextend(char *s,char *t)
{
int n=strlen(s),m=strlen(t),a=;
getpre(s);
while(a<n-&&s[a]==t[a+])a++;
Max[]=a;
a=;
re(k,,n-)
{
int p=a+Max[a]-,l=pre[k-a];
if(k+l->=p)
{
int j=(p-k+)>?(p-k+):;
while(k+j<m&&s[k+j]==t[j])j++;
Max[k]=j;
a=k;
}
else Max[k]=l;
}
}
是不是感觉差不多……
附上lesphere%%%代码:
void getfail(){
fail[]=m;
while(fail[]<n && a[fail[]]==a[fail[]+]) fail[]++;
for(int i=,j=,mx=+fail[];i<n;i++){
if(mx-<i || mx-i==fail[i-j]){
if(i<=mx-) fail[i]=fail[i-j];
while(fail[i]<n && a[fail[i]]==a[fail[i]+i]) fail[i]++;
}
else fail[i]=min(mx-i,fail[i-j]);
if(mx<i+fail[i]) j=i,mx=i+fail[i];
}
}
void getex(){
getfail();
while(ex[]<n && a[ex[]]==b[ex[]]) ex[]++;
for(int i=,j=,mx=ex[];i<n;i++){
if(mx-<i || mx-i==fail[i-j]){
if(i<=mx-) ex[i]=fail[i-j];
while(ex[i]<n && a[ex[i]]==b[ex[i]+i]) ex[i]++;
}
else ex[i]=min(mx-i,fail[i-j]);
if(mx<i+ex[i]) j=i,mx=i+ex[i];
}
}
EXKMP的更多相关文章
- Revolving Digits[EXKMP]
Revolving Digits Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 【无聊放个模板系列】POJ2752 EXKMP
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...
- BNUOJ34990--Justice String (exkmp求最长公共前缀)
Justice String Given two strings A and B, your task is to find a substring of A called justice strin ...
- ExKMP(Z Algorithm) 讲解
目录 问题引入 CaiOJ 1461 [EXKMP]最长共同前缀长度 算法讲解 匹配过程 next 的求解 复杂度证明 代码解决 一些例题 UOJ #5. [NOI2014]动物园 CF1051E V ...
- CodeForces1051E EXKMP + 线段树dp
http://codeforces.com/problemset/problem/1051/E 题意:给你一个很大的数字,然后你可以把这个数字拆分成为任意多个部分,要求每一个部分的数字大小要在一个区间 ...
- HDU3613 Manacher//EXKMP//KMP
http://acm.hdu.edu.cn/showproblem.php?pid=3613 每个字符都有一个权值,将一个字符串分成两半,如果某一半是回文串就把所有的字符权值加起来,否则当0来处理,问 ...
- poj3376 Finding Palindromes【exKMP】【Trie】
Finding Palindromes Time Limit: 10000MS Memory Limit: 262144K Total Submissions:4710 Accepted: 8 ...
- hdu3374 String Problem【最小表示法】【exKMP】
String Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 2018ACM-ICPC南京区域赛M---Mediocre String Problem【exKMP】【Manacher】
这题就单独写个题解吧.想了两天了,刚刚问了一个大佬思路基本上有了. 题意: 一个串$S$,一个串$T$,在$S$中选一段子串$S[i,j]$,在$T$中选一段前缀$T[1,k]$使得$S[i,j]T[ ...
随机推荐
- Spark2 DataSet 创建新行之flatMap
val dfList = List(("Hadoop", "Java,SQL,Hive,HBase,MySQL"), ("Spark", & ...
- 170809、 把list集合中的数据按照一定数量分组
/** * @Desc : 切分list位多个固定长度的list集合(我这是业务需要,直接是1w条数据切分) * @Author : RICK * @Params: [historyList] * @ ...
- 51nod1432 独木舟
1432 独木舟 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 n个人,已知每个人体重.独木舟承重固定,每只独木舟最多坐两个人,可以坐一个人或者 ...
- Alice, Bob, Oranges and Apples CodeForces - 586E
E - Alice, Bob, Oranges and Apples CodeForces - 586E 自己想的时候模拟了一下各个结果 感觉是不是会跟橘子苹果之间的比例有什么关系 搜题解的时候发现了 ...
- Pycharm中如何使用科学计算库
1.简便起见 比起麻烦的安装各种库,我们选择最方便的Anaconda的conda或pip(兼容支持)安装相关库. Pycharm本身缺少numpy和matplotlib这些库,而另一个Python的开 ...
- USB--- kvm in ubuntu:
USB SS=USB SuperSpeed=USB 3.0!!顺应此前的USB 1.1 FullSpeed和USB 2.0 HighSpeed https://jingyan.baidu.com/ar ...
- 《MYSQL必知必会》
1. 同一个数据库中不允许出现同名表:不同的数据库中可以出现同名表2. 每一行记录都用有一个key(一列或一组列作为key)3. 作为key的列不允许值为空(NULL)4. 多个列作为key时,多个列 ...
- Spring@Autowired注解
@Autowired注解可以对成员变量.方法和构造函数进行标注,来完成自动装配的工作. 注意:@Autowired默认是按照类型来注入的. 看下面的例子:例子是以对成员变量(field)为例进行的 p ...
- RESTful URL设计指南(转)
add by zhj: <RESTful Web Services Cookbook>这本书详细介绍了RESTFUL API的设计. 一般来说,一个好的URL,简单明了.这里有一个问题,对 ...
- Html各组件MIME类型
扩展名 类型/子类型 * application/octet-stream 323 text/h323 acx application/internet-property-stream ai appl ...