题意:
给你两个字符串,在第二个串中求一个最长的后缀,同时满足它是第一个串的前缀
分析:
刘雅琼---《扩展KMP》(一看就会)
扩展KMP:在线性的时间内,求出一个串的每个后缀与模式串的最长公共前缀
此题只需判断extend[i] == len - i,那么以i开始的后缀的每个字符都匹配了模式串的前缀
代码:
*#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4+13;
char s[maxn],t[maxn];
int nnext[maxn],extend[maxn];
void getnext(){
int j = 0,tlen = strlen(t);
nnext[0] = tlen;
while(j+1 < tlen && t[j] == t[j+1]) j++;
nnext[1] = j;
int k = 1;
for(int i = 2;i < tlen; ++i){
int p = nnext[k] + k;
int L = nnext[i-k];
if(i + L < p) nnext[i] = L;
else{
j = max(p-i,0);
while(i+j < tlen && t[j] == t[j+i]) j++;
nnext[i] = j;
k = i;
}
}
}
void EKMP(){
int j = 0,tlen = strlen(t),slen = strlen(s);
while(j < tlen && j < slen && s[j] == t[j]) j++;
extend[0] = j;
int k = 0;
for(int i = 1;i < slen; ++i){
int p = k + extend[k];
int L = nnext[i-k];
if(i+L < p) extend[i] = L;
else{
j = max(p-i,0);
while(i+j < slen && j < tlen && s[i+j] == t[j]) j++;
extend[i] = j;
k = i;
}
}
}
int main(){
while(~scanf("%s %s",t,s)){
getnext();
EKMP();
int slen = strlen(s),start = slen;
for(int i = 0;i < slen; ++i){
if(extend[i] == slen-i){
start = i;
break;
}
}
for(int i = start;i < slen; ++i) cout << s[i];
if(slen - start) cout << " " << slen - start << '\n';
else puts("0");
}
return 0;
}