字符串算法模板整理

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=1,j; i<n; ++i) {
 4         for(j=fa[i-1]; ~j&&s[j+1]!=s[i]; j=fa[j]);
 5         fa[i]=s[j+1]==s[i]?j+1:-1;
 6     }
 7 }
 8 int kmp(char* a,char* b,int na,int nb) {
 9     int ret=0;
10     for(int i=0,j=-1; i<nb; ++i) {
11         for(; ~j&&a[j+1]!=b[i]; j=fa[j]);
12         if(a[j+1]==b[i])++j;
13         if(j==na-1)++ret;
14     }
15     return ret;
16 }
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

猜你喜欢

转载自www.cnblogs.com/asdfsag/p/11499092.html