字符串算法模板整理

1.字符串哈希:

1 ll H(ll* h,int l,int r) {return h[r+1]-h[l]*p[r-l+1];}
2 void getH(char* s,ll* h,int n) {h[0]=0; for(int i=1; i<=n; ++i)h[i]=h[i-1]*M+s[i-1];}
View Code

2.KMP:

1 void build(char* s,int n) {
2     fa[0]=-1;
3     for(int i=2,j=0; i<=n; ++i) {
4         for(; ~j&&s[j]!=s[i-1]; j=fa[j]);
5         fa[i]=++j;
6     }
7 }
View Code

3.字典树/AC自动机:

 1 int newnode() {int u=++tot; pre[u]=ed[u]=0; memset(go[u],0,sizeof go[u]); return u;}
 2 void ins(char* s,int x) {
 3     int n=strlen(s),u=1;
 4     for(int i=0; i<n; u=go[u][id[s[i]]],++i)
 5         if(!go[u][id[s[i]]])go[u][id[s[i]]]=newnode();
 6     ed[u]|=1<<x;
 7 }
 8 void build() {
 9     queue<int> q;
10     for(int i=0; i<4; ++i) {
11         if(go[1][i])pre[go[1][i]]=1,q.push(go[1][i]);
12         else go[1][i]=1;
13     }
14     while(q.size()) {
15         int u=q.front();
16         q.pop();
17         ed[u]|=ed[pre[u]];
18         for(int i=0; i<4; ++i) {
19             if(go[u][i])pre[go[u][i]]=go[pre[u]][i],q.push(go[u][i]);
20             else go[u][i]=go[pre[u]][i];
21         }
22     }
23 }
24 void init() {tot=0,newnode();}
View Code

4.后缀自动机:

 1 int newnode(int l) {int u=++tot; mxl[u]=l,memset(go[u],0,sizeof go[u]); return u;}
 2 void add(int ch) {
 3     int p=last,np=last=newnode(mxl[p]+1);
 4     for(; p&&!go[p][ch]; p=fa[p])go[p][ch]=np;
 5     if(!p)fa[np]=1;
 6     else {
 7         int q=go[p][ch];
 8         if(mxl[q]==mxl[p]+1)fa[np]=q;
 9         else {
10             int nq=newnode(mxl[p]+1);
11             memcpy(go[nq],go[q],sizeof go[q]);
12             fa[nq]=fa[q],fa[q]=fa[np]=nq;
13             for(; p&&go[p][ch]==q; p=fa[p])go[p][ch]=nq;
14         }
15     }
16 }
View Code

5.回文树:

 1 struct PAM {
 2     int tot,last,go[N][M],fa[N],mxl[N],siz[N],rt[N],cc[N],nc;
 3     int newnode(int l) {int u=++tot; fa[u]=0,siz[u]=0,mxl[u]=l,memset(go[u],0,sizeof go[u]); return u;}
 4     int getfa(int u) {for(; u&&cc[nc]!=cc[nc-mxl[u]-1]; u=fa[u]); return u;}
 5     void add(int ch) {
 6         cc[++nc]=ch;
 7         int u=getfa(last);
 8         if(!go[u][ch]) {
 9             int v=newnode(mxl[u]+2),p=getfa(fa[u]);
10             fa[v]=go[p][ch]?go[p][ch]:2;
11             go[u][ch]=v;
12         }
13         rt[nc-1]=last=go[u][ch];
14         siz[go[u][ch]]++;
15     }
16     void build(char* s,int n) {
17         tot=nc=0,cc[0]=-1,last=newnode(-1),newnode(0),fa[2]=1;
18         for(int i=0; i<n; ++i)add(s[i]-'a');
19         for(int i=tot; i>=1; --i)siz[fa[i]]+=siz[i];
20     }
21     int getmxl(int r) {return mxl[rt[r]];}
22 };
View Code

6.Manacher:

 1 void Manacher(char* s,int n) {
 2     Ma[0]='$',Ma[1]='#',rd[0]=0;
 3     for(int i=0; i<n; ++i)Ma[(i+1)<<1]=s[i],Ma[((i+1)<<1)+1]='#';
 4     for(int i=1,p=0; i<(n<<1)+2; ++i) {
 5         rd[i]=i<p+rd[p]?min(p+rd[p]-i,rd[(p<<1)-i]):1;
 6         for(; Ma[i+rd[i]]==Ma[i-rd[i]]; ++rd[i]);
 7         if(i+rd[i]>p+rd[p])p=i;
 8     }
 9     for(int i=1; i<(n<<1)+2; ++i)L[i]=R[i]=0;
10     for(int i=1; i<(n<<1)+2; ++i) {
11         L[i+rd[i]-1]=max(L[i+rd[i]-1],rd[i]*2-1);
12         R[i-rd[i]+1]=max(R[i-rd[i]+1],rd[i]*2-1);
13     }
14     for(int i=n<<1; i>=1; --i)L[i]=max(L[i],L[i+1]-2);
15     for(int i=2; i<(n<<1)+2; ++i)R[i]=max(R[i],R[i-1]-2);
16 }
View Code

7.EXKMP:

 1 void getlen(char* a,char* b,int na,int nb,int* ex,int* len) {
 2     for(ex[0]=0; ex[0]<na&&ex[0]<nb&&a[ex[0]]==b[ex[0]]; ++ex[0]);
 3     for(int i=1,p=0; i<na; ++i) {
 4         ex[i]=i<=p+ex[p]?min(p+ex[p]-i,len[i-p]):0;
 5         for(; i+ex[i]<na&&ex[i]<nb&&a[i+ex[i]]==b[ex[i]]; ++ex[i]);
 6         if(i+ex[i]>p+ex[p])p=i;
 7     }
 8 }
 9 void exkmp(char* a,char* b,int na,int nb) {
10     len[0]=nb;
11     getlen(b+1,b,nb-1,nb,len+1,len);
12     getlen(a,b,na,nb,ex,len);
13 }
View Code

8.后缀数组:

 1 void Sort(int* x,int* y,int m) {
 2     for(int i=0; i<m; ++i)c[i]=0;
 3     for(int i=0; i<n; ++i)++c[x[i]];
 4     for(int i=1; i<m; ++i)c[i]+=c[i-1];
 5     for(int i=n-1; i>=0; --i)sa[--c[x[y[i]]]]=y[i];
 6 }
 7 void da(int* s,int n,int m=1000) {
 8     int *x=buf1,*y=buf2;
 9     x[n]=y[n]=-1;
10     for(int i=0; i<n; ++i)x[i]=s[i],y[i]=i;
11     Sort(x,y,m);
12     for(int k=1; k<n; k<<=1) {
13         int p=0;
14         for(int i=n-k; i<n; ++i)y[p++]=i;
15         for(int i=0; i<n; ++i)if(sa[i]>=k)y[p++]=sa[i]-k;
16         Sort(x,y,m),p=1,y[sa[0]]=0;
17         for(int i=1; i<n; ++i)y[sa[i]]=x[sa[i-1]]==x[sa[i]]&&x[sa[i-1]+k]==x[sa[i]+k]?p-1:p++;
18         if(p==n)break;
19         swap(x,y),m=p;
20     }
21 }
22 void getht() {
23     for(int i=0; i<n; ++i)rnk[sa[i]]=i;
24     ht[0]=0;
25     for(int i=0,k=0; i<n; ++i) {
26         if(k)--k;
27         if(!rnk[i])continue;
28         for(; s[i+k]==s[sa[rnk[i]-1]+k]; ++k);
29         ht[rnk[i]]=k;
30     }
31 }
32 void initST() {
33     for(int i=1; i<n; ++i)ST[i][0]=ht[i];
34     for(int j=1; (1<<j)<=n; ++j)
35         for(int i=1; i+(1<<j)-1<n; ++i)
36             ST[i][j]=min(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
37 }
38 int lcp(int l,int r) {
39     if(l==r)return n-sa[l];
40     if(l>r)swap(l,r);
41     l++;
42     int k=Log[r-l+1];
43     return min(ST[l][k],ST[r-(1<<k)+1][k]);
44 }
View Code

9.序列自动机:

1 void build() {
2     for(int i=0; i<M; ++i)go[n][i]=go[n+1][i]=n+1;
3     for(int i=n-1; i>=0; --i)memcpy(go[i],go[i+1],sizeof go[i]),go[i][s[i]-'a']=i+1;
4 }
View Code

 

posted @ 2019-09-10 19:31  jrltx  阅读(170)  评论(0编辑  收藏  举报