(我和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的更多相关文章

  1. Revolving Digits[EXKMP]

    Revolving Digits Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  2. 【无聊放个模板系列】POJ2752 EXKMP

    #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...

  3. BNUOJ34990--Justice String (exkmp求最长公共前缀)

    Justice String Given two strings A and B, your task is to find a substring of A called justice strin ...

  4. ExKMP(Z Algorithm) 讲解

    目录 问题引入 CaiOJ 1461 [EXKMP]最长共同前缀长度 算法讲解 匹配过程 next 的求解 复杂度证明 代码解决 一些例题 UOJ #5. [NOI2014]动物园 CF1051E V ...

  5. CodeForces1051E EXKMP + 线段树dp

    http://codeforces.com/problemset/problem/1051/E 题意:给你一个很大的数字,然后你可以把这个数字拆分成为任意多个部分,要求每一个部分的数字大小要在一个区间 ...

  6. HDU3613 Manacher//EXKMP//KMP

    http://acm.hdu.edu.cn/showproblem.php?pid=3613 每个字符都有一个权值,将一个字符串分成两半,如果某一半是回文串就把所有的字符权值加起来,否则当0来处理,问 ...

  7. poj3376 Finding Palindromes【exKMP】【Trie】

    Finding Palindromes Time Limit: 10000MS   Memory Limit: 262144K Total Submissions:4710   Accepted: 8 ...

  8. hdu3374 String Problem【最小表示法】【exKMP】

    String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  9. 2018ACM-ICPC南京区域赛M---Mediocre String Problem【exKMP】【Manacher】

    这题就单独写个题解吧.想了两天了,刚刚问了一个大佬思路基本上有了. 题意: 一个串$S$,一个串$T$,在$S$中选一段子串$S[i,j]$,在$T$中选一段前缀$T[1,k]$使得$S[i,j]T[ ...

随机推荐

  1. zookeeper学习资料汇总

    zookeeper入门介绍   (1) zookeeper入门介绍     (2) zookeeper应用场景介绍 (淘宝团队)   (3) 分布式服务框架 Zookeeper -- 管理分布式环境中 ...

  2. jQuery ajax的前台代码编写

    jQuery ajax的前台代码: <script type="text/javascript" src="/include/jquery/jquery-1.1.3 ...

  3. 安装中文输入法 ubuntu shortcut desktop

    安装中文输入法 Kali自带是不能输入中文的,因此我安装了搜狗输入法和谷歌输入法(我做备份的),安装其一便可以.建议安装前apt-get update下,刷新下.其次安装好任意输入法需要重启下才能正常 ...

  4. SpringMVC:JSON形式输出(基于Fastjson)

    在Spring3.0中,@ResponseBody标记可以将对象"封装"为JSON形式的数据,并输出,下面的例子中使用的是阿里的Fastjson JSONaz解析工具,在sprin ...

  5. Chrome百度不显示中文字体

    chrome://flags/ 启用DirectWrite 关闭就可以了

  6. 深入浅出REST(转载)

    add by zhj: 参考http://zh.wikipedia.org/zh/REST 需要注意的是,REST是设计风格而不是标准,它也并没有与哪种协议绑定.不过,我们常按REST设计风格来使用H ...

  7. 【虫师讲Selenium+Python】第三讲:操作测试对象

    一.首先呢,选择一个编辑器,我们这里选择的是Sublime Text >Ctrl+B为运行当前脚本的快捷方式 二.编写代码 #coding==utf-8 from selenium import ...

  8. CentOS7.1.x+Druid 0.12 集群配置

    原文转载自:https://blog.csdn.net/bigtree_3721/article/details/79583008 先决条件:安装版本列表 本次安装满足下面的条件: CentOS v7 ...

  9. 实习培训——Servlet(5)

    实习培训——Servlet(5) 1  Servlet 简介 Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HT ...

  10. MVC杂碎笔记

    MVC页面中@相当于aspx中的<%%>一样,@后面可以写代码的,一般用来放变量的 --  在Controller中方法的前面加[HttpGet]表示该方法只处理http的 GET 请求, ...