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[ ... 
随机推荐
- centos6.9环境下JDK安装部署
			1.准备jdk安装文件: 这里我使用的是 jdk-7u79-linux-x64.tar.gz 2.在 /usr/local 目录下创建 sotfware目录,并上传JDK文件: 解压文件并修改文件夹为 ... 
- 微信小程序中target与currentTarget
			target在事件流的目标阶段:currentTarget在事件流的捕获,目标及冒泡阶段.但事件流处于目标阶段,target与currentTarget指向一样, 而当处于捕获和冒泡阶段的时候,tar ... 
- ubuntu-server-18.04 设置开机启动脚本
			ubuntu-16.10 开始不再使用initd管理系统,改用systemd systemd is now used for user sessions. System sessions had al ... 
- FZU 2252 Yu-Gi-Oh!(枚举+贪心)
			Problem 2252 Yu-Gi-Oh! Accept: 105 Submit: 628 Time Limit: 1000 mSec Memory Limit : 32768 KB ... 
- 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. ... 
- Primitive Data Types
			Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics) http ... 
- Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)
			事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ... 
- java动态加载
			先贴个笔记,后续用得着再深究. package test; import java.io.File; import java.io.IOException; import java.lang.refl ... 
- GDB常用命令使用说明(一)
			本文由霸气的菠萝原创,转载请注明出处:http://www.cnblogs.com/xsln/p/gdb_instructions1.html 全部关于gdb的文章索引请点这里 GDB(GNU Deb ... 
- Andrew Ng-ML-第十九章-应用举例:照片OCR(光学字符识别)
			1.问题描述与 OCR pipeline 图1.图像文字识别流水线 首先是输入图片->进行文字检测->字符分割->字符识别. 这些阶段分别需要1-5人这样子. 2.滑动窗口 主要讲滑 ... 
