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=2,j=0; i<=n; ++i) { 4 for(; ~j&&s[j]!=s[i-1]; j=fa[j]); 5 fa[i]=++j; 6 } 7 }
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 }
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 }
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 }