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];}
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 }
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();}
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 }
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 };
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 }
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 }