【模板】扩展KMP
https://blog.csdn.net/dyx404514/article/details/41831947
定义和KMP不一样,同时程序实现非常复杂。建议背下来。主要是利用 d p dp dp的思想。
时间复杂度证明:每个点只会被枚举一次。所以是 O ( n ) O(n) O(n)。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
char a[N],b[N];
int nxt[N],ex[N];
void get_nxt(char *str) {
int i,j=0,po,len=strlen(str);
nxt[0]=len;
while(str[j]==str[j+1]&&j+1<len) j++;
nxt[1]=j;
po=1;
for(int i=2;i<len;i++) {
//we can not equal
if(nxt[i-po]+i<nxt[po]+po)//这里隐含着p>i
nxt[i]=nxt[i-po];
else {
j=nxt[po]+po-i;
if(j<0) j=0;
while(i+j<len&&str[i+j]==str[j]) j++;
nxt[i]=j;
po=i;
}
}
}
void exkmp(char *s1,char *s2) {
int i,j=0,po,l1=strlen(s1),l2=strlen(s2);
get_nxt(s2);
while(s2[j]==s1[j]&&j<l1&&j<l2) j++;
ex[0]=j;
po=0;
for(int i=1;i<l1;i++) {
//strange:po=0 -> i-po=i???
//it seems that 相比上一个,少处理了一个
//but nxt[0] is meaningless
//it must be ex[po]
//because string is different
//it must be nxt[i-po]
//because string is the same
//we can not equal
if(nxt[i-po]+i<ex[po]+po)//这里隐含着p>i
ex[i]=nxt[i-po];
else {
j=ex[po]+po-i;
if(j<0) j=0;
while(i+j<l1&&j<l2&&s1[i+j]==s2[j]) j++;
ex[i]=j;
po=i;
}
}
}
int main() {
scanf("%s %s",a,b);
exkmp(a,b);
for(int i=0;i<strlen(a);i++) printf("%d ",ex[i]);
}

浙公网安备 33010602011771号