kmp
首先,让我们看一个讲解(这里讲的很透彻了)
一个字符串最小周期(例如ab是ababab的周期)是\(len-nxt[len](2*nxt[len]>len)\)。
一个字符串:\(———|——|——|——|——|——|———\)
前面去\(nxt[len]:\quad\quad\quad\
|——|——|——|——|——|———\)
后面去\(nxt[len]:
———|——|——|——|——|——|\)
eg
一字符串最小公共前缀可通过\(nxt[len]\)不断\(j=nxt[j]\)向下跳得到(eg:http://noip.ybtoj.com.cn/contest/876/problem/3)
求几个字符串的最长公共子串
先找出长度最短的串,设它长度为mnlen,将他的每个子串[i~mnlen]作为模式串与其他字符串匹配最长前缀(eg:http://noip.ybtoj.com.cn/contest/876/problem/5)
- 注:一些题可以先不考虑某些限制,进行预处理,等后面再考虑。(eg:http://noip.ybtoj.com.cn/contest/876/problem/6)
已知\(nxt\)数组(循环节)构造字符串
(循环节\(pre[i]\),\(nxt[i]=n-pre[i]\))
反kmp,若\(nxt[i]>0\),则\(s[i]=s[nxt[i]]\),
否则将\(1\)~\(nxt[i-1]\)中用\(j=nxt[j]\)跳到的所有点设为\(i\)位置不可选,再选\(i\)位置
(eg:http://noip.ybtoj.com.cn/contest/876/problem/7)
给一字符串a,问它有几个子串通过字符交换能变为另个字符串b(题面及代码见:http://noip.ybtoj.com.cn/contest/876/problem/8)
设\(pre[x]\)表示x上一次出现位置,则\(a[i]\)与上个\(a[i]\)距离为\(i-pre[a[i]]\),所以\(s[i]=i-pre1[a[i]],t[i]=i-pre[b[i]]\),对\(s,t\)进行\(kmp\)匹配,注意匹配时不能超边界(详见代码)。

浙公网安备 33010602011771号