字符串

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;
  }
}
posted @ 2024-03-01 09:38  lgh_2009  阅读(3)  评论(0编辑  收藏  举报