KMP
void getnxt(int m,char t[],int nxt[]){
nxt[1]=0;
for(int i=2,j=0;i<=m;i++){
while(j&&t[j+1]!=t[i])j=nxt[j];
if(t[j+1]==t[i])j++;
nxt[i]=j;
}
}
int kmp(int n,char s[],int m,char t[],int nxt[],int ans[]){
int cnt=0;
for(int i=1,j=0;i<=n;i++){
while(j&&t[j+1]!=s[i])j=nxt[j];
if(t[j+1]==s[i])j++;
if(j==m)ans[++cnt]=i-m+1;
}
return cnt;
}
扩展KMP
void getz(int m,char t[],int z[]){
z[1]=m;
for(int i=2,l=0,r=0;i<=m;i++){
if(i<=r)z[i]=min(z[i-l+1],r-i+1);
while(i+z[i]<=m&&t[i+z[i]]==t[1+z[i]])z[i]++;
if(i+z[i]-1>r)l=i,r=i+z[i]-1;
}
}
void exkmp(int n,char s[],int m,char t[],int z[],int ext[]){
for(int i=1,l=0,r=0;i<=n;i++){
if(i<=r)ext[i]=min(z[i-l+1],r-i+1);
while(i+ext[i]<=n&&s[i+ext[i]]==t[1+ext[i]])ext[i]++;
if(i+ext[i]-1>r)l=i,r=i+ext[i]-1;
}
}
AC自动机
#include<bits/stdc++.h>
using namespace std;
template<int maxn1,int maxn2>struct ACAM{
int tr[maxn1][maxn2],vis[maxn1],cnt,fail[maxn1];
int to_num(char c){
return c-'a';
}
void insert(string a,int pos=0){
for(int i=0;i<a.size();i++){
int t=to_num(a[i]);
if(!tr[pos][t])tr[pos][t]=++cnt;
pos=tr[pos][t];
}
vis[pos]++;
}
void build(){
queue<int>q;
for(int i=0;i<maxn2;i++)if(tr[0][i])fail[tr[0][i]]=0,q.push(tr[0][i]);
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=0;i<maxn2;i++){
if(tr[now][i])fail[tr[now][i]]=tr[fail[now]][i],q.push(tr[now][i]);
else tr[now][i]=tr[fail[now]][i];
}
}
}
int query(string a,int pos=0,int ans=0){
for(int i=0;i<a.size();i++){
pos=tr[pos][to_num(a[i])];
for(int j=pos;j&&vis[j]!=-1;j=fail[j])ans+=vis[j],vis[j]=-1;
}
return ans;
}
};
后缀数组
void getsa(int n,int m,char s[],int sa[],int rk[],int ht[])
{
int x[n+5],y[n+5],b[max(m,n)+5];
memset(x,0,sizeof(x)),memset(y,0,sizeof(y)),memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)b[x[i]=s[i]]++;
for(int i=1;i<=m;i++)b[i]+=b[i-1];
for(int i=n;i>=1;i--)sa[b[x[i]]--]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=n-k+1;i<=n;i++)y[++p]=i;
for(int i=1;i<=n;i++)if(sa[i]>k)y[++p]=sa[i]-k;
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)b[x[i]]++;
for(int i=1;i<=m;i++)b[i]+=b[i-1];
for(int i=n;i>=1;i--)sa[b[x[y[i]]]--]=y[i];
for(int i=1;i<=n;i++)swap(x[i],y[i]);
p=0;
for(int i=1;i<=n;i++)x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
if(p==n)break;
m=p;
}
for(int i=1;i<=n;i++)rk[sa[i]]=i;
for(int i=1,k=0;i<=n;i++){
if(k)k--;
while(s[i+k]==s[sa[rk[i]-1]+k])k++;
ht[rk[i]]=k;
}
}
Manacher
void manacher(int n,char s[],int d[]){
for(int i=0,r=0,mid;i<=n;i++){
d[i]=i<r?min(d[mid*2-i],r-i):1;
while(s[i+d[i]]==s[i-d[i]])d[i]++;
if(i+d[i]>r)r=i+d[i],mid=i;
}
}