Automatic suffix machine
//confirm the MAXN size, typically twice times the maximum value of the original string length, then init (), and finally a single character insert,//Convert to the corresponding number, call the Insert function, can support online. structsam{intch[maxn][ -]; intPRE[MAXN],STEP[MAXN]; intLast,id; voidinit () { last=id=0; memset (ch[0],-1,sizeof(ch[0])); pre[0]=-1; step[0]=0; } voidInsert (intc) {intp=last,np=++ID; STEP[NP]=step[p]+1; memset (CH[NP],-1,sizeof(CH[NP])); while(p!=-1&&ch[p][c]==-1) ch[p][c]=np,p=Pre[p]; if(p==-1) pre[np]=0; Else { intq=Ch[p][c]; if(step[q]!=step[p]+1) { intnq=++ID; memcpy (Ch[nq],ch[q],sizeof(Ch[q])); STEP[NQ]=step[p]+1; PRE[NQ]=Pre[q]; PRE[NP]=pre[q]=NQ; while(p!=-1&&CH[P][C]==Q) ch[p][c]=nq,p=Pre[p]; } Elsepre[np]=Q; } Last=NP; /*//Query the number of substrings that appear at least k times while (np!=-1&&num[np]<k)//Do not reach K times add 1 {num[np]++; if (num[np]>=k) ANS+=STEP[NP]-STEP[PRE[NP]]; Add the answer NP=PRE[NP]; } */ } /*int getcnt ()//can query how many different sub-strings {int ret=0; for (int i=id;i>=1;i--) ret+=step[i]-step[pre[i]]; return ret; } */}sam;
View Code
Longest common substring of multiple strings (suffix automaton)
/*Test Instructions: Give a number of strings, the length of not more than 100000, to find the longest common continuous string parsing: suffix automata, the first string input to build a suffix automaton, in the Sam add two Max[i] (query with the first node is the last character of the suffix of the maximum length), Min I (The minimum value in all queries Max[i].) */#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<vector>#include<cmath>using namespacestd;Const intmaxn=200005;structsam{intch[maxn][ -]; intPRE[MAXN],STEP[MAXN]; intLast,id; intMIN[MAXN],MAX[MAXN]; voidInit ()//Initialize{ Last=id=0; memset (ch[0],-1,sizeof(ch[0])); pre[0]=-1; step[0]=0; min[0]=max[0]=0; } voidInsert (intC//template, own Baidu { intp=last,np=++ID; STEP[NP]=step[p]+1; memset (CH[NP],-1,sizeof(CH[NP])); MIN[NP]=max[np]=STEP[NP]; while(p!=-1&&ch[p][c]==-1) ch[p][c]=np,p=Pre[p]; if(p==-1) pre[np]=0; Else { intq=Ch[p][c]; if(step[q]!=step[p]+1) { intnq=++ID; memcpy (Ch[nq],ch[q],sizeof(Ch[q])); STEP[NQ]=step[p]+1; MIN[NQ]=max[nq]=STEP[NQ]; PRE[NQ]=Pre[q]; PRE[NP]=pre[q]=NQ; while(p!=-1&&CH[P][C]==Q) ch[p][c]=nq,p=Pre[p]; } Elsepre[np]=Q; } Last=NP; } voidFind (Char*S) {intlen=strlen (S); intu=0, d=0; for(intI=0; i<=id;i++) max[i]=0; for(intI=0; i<len;i++) { intc=s[i]-'a'; if(ch[u][c]!=-1) d++,u=Ch[u][c]; Else { while(u!=-1&&ch[u][c]==-1) u=Pre[u]; if(u!=-1) d=step[u]+1, u=Ch[u][c]; Elseu=0, d=0; } Max[u]=max (MAX[U],D);//Update } for(inti=id;i>=1; i--) max[pre[i]]=Max (max[pre[i]],max[i]); for(intI=0; i<=id;i++) min[i]=min (min[i],max[i]); } intGetans () {intret=0; for(intI=0; i<=id;i++) ret=Max (ret,min[i]); returnret; }}sam;CharS[MAXN];intMain () {scanf ("%s", S); intlen=strlen (S); Sam.init (); for(intI=0; i<len;i++) Sam. Insert (s[i]-'a'); while(SCANF ("%s", S)! =EOF) Sam. Find (S); printf ("%d\n", Sam. Getans ()); return 0;}
View Code
Binary Graph matching Template
//Maxn,n The maximum value of points in two squares, first init, then add edge Addedge in the input,//Last Call solvestructedge{intV,next;} e[2*MAXN];structtwomatch{intHead[maxn],eid; BOOLVIS[MAXN]; intN,TO[MAXN]; voidInitintnn) {N=nn; Eid=0; for(intI=1; i<=n;i++) head[i]=-1; } voidAddedge (intUintv) {e[++eid].v=v; E[eid].next=head[u]; head[u]=Eid; } BOOLDfsintu) { for(inti=head[u];i!=-1; i=E[i].next) { intv=e[i].v; if(Vis[v])Continue; VIS[V]=true; if(to[v]==-1||DFS (To[v])) {To[v]=u; return true; } } return false; } intsolve () {intans=0; for(intI=1; i<=n;i++) to[i]=-1; for(intI=1; i<=n;i++) {memset (Vis,false,sizeof(VIS)); if(Dfs (i)) ans++; } returnans; }}tm;
View Code
Monotonic Stacks
int rear=0; for (int st=1; st<=n;st++) { while (rear>0&&h[que[rear] ]>=H[ST]) --rear; if (rear==0) le[st]=0; Else le[st]=Que[rear]; que[++rear]=St;}
View Code
Monotone queue
intQUE[MAXN],ELEM[MAXN]; intf=1, r=0; for(intI=1; i<k;i++) { while(R>=f&&elem[que[r]]>=elem[i])--R; que[++r]=i; } for(inti=k;i<=n;i++) { while(R>=f&&elem[que[r]]>=elem[i])--R; que[++r]=i; while(que[f]+k<=i) + +F; Min[i-k]=Elem[que[f]]; }
View Code
Template for Competitions