String Rush
KMP
https://www.luogu.com.cn/problem/P3375
KMP 本质是求前缀最长 bd。具体来说:
while(kmp[i]&&cr[kmp[i]+1]^cr[i])kmp[i]=kmp[ kmp[i] ];
if(a[kmp[i]+1]==a[i])kmp[i]++;
最小表示法
https://www.luogu.com.cn/problem/P1368
首先断环为二倍链。
每次都让字典序较大的那一个右移一位。
\(O(n)\)。
int work(){
int poi1=1,poi2=2,len=1;
while(poi1<=n&&poi2<=n&&len<=n){
int p=a[poi1+len-1],q=a[poi2+len-1];
if(p==q)len++;
if(p>q)poi1+=len,len=1;
if(p<q)poi2+=len,len=1;
if(poi1==poi2)poi1++;
}
return min(poi1,poi2);
}
Manacher
https://www.luogu.com.cn/problem/P3805
注意要两两间插分割符号!!
设 \(man_i\) 为以 \(i\) 为中心的最长回文串半径。
则首先是对称, \(man_i=\min(man_{2M-i},wl-i)\)。
其次是推自己,while(cr[i-man[i]]==cr[i+man[i]])++man[i]
。
最后是推墙。
int wl=1,M=0;
rep(i,1,n){
int z=M*2-i;
man[i]=min(man[z],wl-i);
while(cr[ i-man[i] ]==cr[ i+man[i] ])man[i]++;
if(i+man[i]>wl)wl=i+man[i],M=i;
}
PAM
见我博客。
SAM
不会。
后缀树
会。但是好像板子题都被我刷一遍了找不到好的练手题了。
CF1073G - Yet Another LCP Problem
https://www.luogu.com.cn/problem/CF1073G
树剖死了,因为 2log。直接上虚树即可。
P5212 - SubString
https://www.luogu.com.cn/problem/P5212
LCT。
但是有时间再写吧,因为不想 debug。