exkmp


与 kmp 思想相似因而也被称作扩展kmp算法,用于在 \(O(n+m)\) 的复杂度内求解长度为 \(n\) 的字符串 \(S\) 的所有后缀与长度为 \(m\) 的字符串 \(T\) 的最长公共前缀。

\(next\)

对模式串 \(T\) 构建 \(next\) 数组,其中 \(nxt[i]\) 表示 \(T_{i\sim n}\)\(T\) 的最长公共前缀长度。

对于 \(\forall x \in [2,n]\) ,假设 \(\forall i\in [2,x)\ nxt[i]\) 都已求出,则求解 \(nxt[x]\) 的过程如下:

\(nxt[i]+i-1\) 的最大值为 \(p=k+nxt[k]-1\),即目前匹配到的最长前缀。

懒得画图,直接说结论吧,以后看博客复习就 就 再手推一遍(

\(L=nxt[x-k]\)

\(x+L\leq p\)\(nxt[x]=L\)

否则从 \(p-x+1\)\(p+1\) 开始暴力匹配(

\(extend\)

\(nxt\) 数组的构建方式一致。

#include 
using namespace std;

long long read()
{
	long long res=0,p=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')p=-1; ch=getchar();}
	while(isdigit(ch)) res=res*10+ch-'0',ch=getchar();
	return res*p;
}

const int maxn=2e7+10;

char s[maxn],t[maxn];
int nxt[maxn],ext[maxn],n,m,len;
long long ans=0,k,p,L;

inline int getPn(int id) {return id+nxt[id]-1;}
inline int getPe(int id) {return id+ext[id]-1;}

void gNxt()
{
	nxt[0]=n,k=1;
	for(int i=1;i>t>>s;
	n=strlen(s),m=strlen(t),len=min(n,m);
	gNxt(),gExt();
	for(int i=0;i