字符串问题,要求出一个串S的所有后缀与另一个串T的最长公共前缀。
这个好像可以后缀数组做诶,不过我们有一个 O(n)O(n) 的做法,且码量极小。

扩展KMP可以求出一个串 TT 的所有后缀与它本身的最长公共前缀。我们如果可以做这个问题的话,那么构造一个串 T+'#'+S 就可以跑一遍扩展KMP求出答案了。

跟马拉车一样的思路,尽量运用之前已经求出过的东西。看代码吧,而且这个画图比较好理解。

void getz(char *s,int n){
    z[1]=n;s[n+1]=0;
    for(int i=2,l=0,r=0;i<=n;i++){
        z[i]=i<=r?min(z[i-l+1],r-i+1):0;//这个串与某一个前缀相等,那就利用那个前缀求出的东西。
        while(s[i+z[i]]==s[1+z[i]])z[i]++;//while执行 O(n)次
        if(i+z[i]-1>r)r=i+z[i]-1,l=i;
    }
}

然后就没有了。。题目有 最长重复子串CF1313E
一般就是如果想求一些LCP的话,先观察一下要求的串的位置关系,如果满足其中一个串的起始位置是不动的,另一个串要对所有起始位置求,那么就直接上扩展KMP就行了。。