(我和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. centos6.9环境下JDK安装部署

    1.准备jdk安装文件: 这里我使用的是 jdk-7u79-linux-x64.tar.gz 2.在 /usr/local 目录下创建 sotfware目录,并上传JDK文件: 解压文件并修改文件夹为 ...

  2. 微信小程序中target与currentTarget

    target在事件流的目标阶段:currentTarget在事件流的捕获,目标及冒泡阶段.但事件流处于目标阶段,target与currentTarget指向一样, 而当处于捕获和冒泡阶段的时候,tar ...

  3. ubuntu-server-18.04 设置开机启动脚本

    ubuntu-16.10 开始不再使用initd管理系统,改用systemd systemd is now used for user sessions. System sessions had al ...

  4. FZU 2252 Yu-Gi-Oh!(枚举+贪心)

    Problem 2252 Yu-Gi-Oh! Accept: 105    Submit: 628 Time Limit: 1000 mSec    Memory Limit : 32768 KB   ...

  5. MySQL NDB集群安装配置(mysql cluster 9.4.13 installation)

    一.安装前规划 1.安装软件版本:mysql-cluster-gpl-7.4.13-linux-glibc2.5-x86_64.tar.gz 2.安装规划: 主机名 Ip地址 角色 db01 192. ...

  6. Primitive Data Types

    Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics) http ...

  7. Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)

    事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...

  8. java动态加载

    先贴个笔记,后续用得着再深究. package test; import java.io.File; import java.io.IOException; import java.lang.refl ...

  9. GDB常用命令使用说明(一)

    本文由霸气的菠萝原创,转载请注明出处:http://www.cnblogs.com/xsln/p/gdb_instructions1.html 全部关于gdb的文章索引请点这里 GDB(GNU Deb ...

  10. Andrew Ng-ML-第十九章-应用举例:照片OCR(光学字符识别)

    1.问题描述与 OCR pipeline 图1.图像文字识别流水线 首先是输入图片->进行文字检测->字符分割->字符识别. 这些阶段分别需要1-5人这样子. 2.滑动窗口 主要讲滑 ...