Luogu P5410【模板】扩展 KMP

题意:求 (T)(S) 的每个后缀的最长公共前缀。

先令 (s=S+T)(z[i]) 表示 (T)(suff_i) 的最长公共前缀。

(注意下标是从 (0) 开始的)

(z[i]=min(z[i-l],r-i+1)) ,前一部分如图:

后一部分是要保证不能越过最靠右的边界,因为更靠右的部分无法判断是否相等。

#include<iostream>
#include<cstdio>
#include<cstring>
#define R register int
using namespace std;
namespace Luitaryi {
const int N=100010;
int n,m,z[N<<1];
char s[N<<1],t[N];
inline void main() {
  scanf("%s",t);
  scanf("%s",s),n=strlen(s);
  s[n]='#',memcpy(s+n+1,t,strlen(t));
  for(R i=1,l=0,r;s[i];++i) {
    if(i<=r) z[i]=min(z[i-l],r-i+1);
    while(s[z[i]]==s[i+z[i]]) ++z[i];
    if(i+z[i]-1>r) r=i+z[i]-1,l=i;
  } printf("%d ",n);
  for(R i=1;i<n;++i) printf("%d ",z[i]);
  puts("");
  for(R i=n+1;s[i];++i) printf("%d ",z[i]);
}
} signed main() {Luitaryi::main(); return 0;}

2019.01.09

原文地址:https://www.cnblogs.com/Jackpei/p/12177373.html