Spoj1811 gives two lengths of less than 100000 strings A and B to find their longest common contiguous substring.
First, the string A is constructed as a SAM, and then the robot is run with B as follows.
A variable LCS is used to record the current longest common substring, initialized to 0.
Set the current state node is P, to match the character is C, if GO[C] has an edge, indicating the ability to transfer the state, then transfer and lcs++;
If not, move the state to par of P, and repeat the process until P returns to the root node if it still cannot be transferred, and set the LCS to 0;
If you enter a state that can be transferred in the previous procedure, set the LCS to the current state of Val.
Why should I move to par after the mismatch? Because the mismatch on state p indicates that the string represented by [Min,max] in the state is not a substring in B, but a suffix shorter than theirs may still be a substring of B, and the par pointer exactly points to the suffix of that state.
spoj1812 requires the longest common substring of multiple strings, n<=100000,10 a string.
Would have wanted to use the generalized Sam, and then to each point position pressure 10 bit to indicate which string it can go to, and finally DFS again.
20*10^5=10^6 a point, time pressure is very tight direct timeout.
Referring to the previous practice, put a string A in, nlcs[x] maintain the current string and a in the robot x node matching the maximum length, lcs[x] maintenance of the first I string. Finish a string after for once, X did not go to the point lcs[x]=0, the rest of the Lcs[x]=minn (Lcs[x],nlcs[x]);
spoj1811
#include <cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespacestd;Const intn=2*100010;CharA[n],b[n];intal,bl,tot,last,son[n][ -],step[n],pre[n];intMaxxintXintY) {returnX>y?x:y;}intAdd_node (intx) {step[++tot]=x; returntot;}voidExtendintch) { intP=last,np=add_node (step[p]+1); while(P &&!son[p][ch]) son[p][ch]=np,p=Pre[p]; if(!p) pre[np]=1; Else { intq=Son[p][ch]; if(step[q]==step[p]+1) pre[np]=P; Else { intNq=add_node (step[p]+1); memcpy (Son[nq],son[q],sizeof(Son[q])); PRE[NQ]=Pre[q]; PRE[Q]=pre[np]=NQ; while(son[p][ch]==q) son[p][ch]=nq,p=Pre[p]; }} last=NP;}intMain () {Freopen ("a.in","R", stdin); //freopen ("Me.out", "w", stdout);Memset (son,0,sizeof(son)); memset (PRE,0,sizeof(pre)); memset (step,0,sizeof(step)); Tot=0; Add_node (0); last=1; scanf ("%s%s", A +1, B +1); Al=strlen (A +1), Bl=strlen (b +1); for(intI=1; i<=al;i++) Extend (a[i]-'a'+1); intch,x=1, ans=0, len=0; for(intI=1; i<=bl;i++) {ch=b[i]-'a'+1; while(x &&!son[x][ch]) x=pre[x],len=step[x];if(x==0) x=1; if(Son[x][ch]) x=son[x][ch],len++; Ans=maxx (Ans,len);} printf ("%d\n", ans); return 0;}
spoj1812
#include <cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespacestd;Const intn=2*100010;Chars[ the][n];intn,tot,last,son[n][ -],step[n],pre[n],lcs[n],nlcs[n],l[ the];BOOLVis[n];structnode{intX,y,next;} a[2*N];intMaxxintXintY) {returnX>y?x:y;}intMinn (intXintY) {returnX<y?x:y;}intAdd_node (intx) {step[++tot]=x;lcs[tot]=x; returntot;}voidExtendintch) { intP=last,np=add_node (step[p]+1); while(P &&!son[p][ch]) son[p][ch]=np,p=Pre[p]; if(!p) pre[np]=1; Else { intq=Son[p][ch]; if(step[q]==step[p]+1) pre[np]=P; Else { intNq=add_node (step[p]+1); memcpy (Son[nq],son[q],sizeof(Son[q])); PRE[NQ]=Pre[q]; PRE[Q]=pre[np]=NQ; while(son[p][ch]==q) son[p][ch]=nq,p=Pre[p]; }} last=NP;}voidSolveintID) {memset (NLCS,0,sizeof(NLCS)); memset (Vis,0,sizeof(VIS)); intx=1, len=0, ch; for(intI=1; i<=l[id];i++) {ch=s[id][i]-'a'+1; while(x &&!)Son[x][ch]) {x=pre[x],len=step[x],vis[x]=1; NLCS[X]=Maxx (Nlcs[x],len); } if(x==0) x=1, vis[1]=1; if(Son[x][ch]) x=son[x][ch],vis[x]=1, len++; NLCS[X]=Maxx (Nlcs[x],len); } for(intI=1; i<=tot;i++) if(!vis[i]) lcs[i]=0; Elselcs[i]=Minn (lcs[i],nlcs[i]);}intMain () {Freopen ("a.in","R", stdin); //freopen ("Me.out", "w", stdout);Memset (son,0,sizeof(son)); memset (PRE,0,sizeof(pre)); memset (step,0,sizeof(step)); Tot=0; Add_node (0); last=1; n=0; while(SCANF ("%s", s[++n]+1)!=EOF) {L[n]=strlen (s[n]+1); }n--; for(intI=1; i<=l[1];i++) Extend (s[1][i]-'a'+1); for(intI=2; i<=n;i++) solve (i); intans=0; for(intI=1; i<=tot;i++) ans=Maxx (Ans,lcs[i]); printf ("%d\n", ans); return 0;}
"Spoj1811 & spoj1812-lcs1 & LCS2" Sam