Because Sam wants to be concise ... So I wrote the question again ...
But it's good to learn something new ...
here 's how to use SA to do this problem.
First, as with two strings, build a Sam for the first string
And then each string runs on this Sam and matches it.
But what is the answer to our final question?
is a state substring that has the largest minimum value of the matching length in all strings
And then for each string
We can record its maximum matching length on each state substring.
Finally, a very critical shift is needed.
is to update the node pointed to by the fail pointer with the value of the current node
For example, this situation
If one matches to the left three nodes at a time, match to the two nodes on the right (two matches in different strings)
So obviously, the common substring length of these two strings is 2 is present
But since we haven't moved, the point pointed to by the fail pointer does not store the previous information and then it goes wrong.
And then as for the order of transfer, we can follow the depth sequence
This can be achieved with a bucket row.
1 Program bzoj2946;2 ConstMAXN =100010;3 varN,i,j,now,maxl,root,c,tot,cnt,t:longint;4s:array[1..5]of ansistring;5mx,fail,q,b,ans,tem:array[-1.. Maxn]of Longint;6a:array[-1.. maxn,-1.. -]of Longint;7 8 function Max (a,b:longint): Longint;9 beginTen ifA>b then exit (a)Elseexit (b); One end; A - function min (a,b:longint): Longint; - begin the ifA<b then exit (a)Elseexit (b); - end; - - function Insert (p,c:longint): Longint; + varNp,q,nq:longint; - begin +Inc (CNT); np:=cnt;mx[np]:=mx[p]+1; A while(p<>0) and (a[p,c]=0) Do at begin -a[p,c]:=np;p:=Fail[p]; - end; - ifp=0Then Fail[np]:=rootElse - begin -q:=A[p,c]; in ifmx[q]=mx[p]+1Then fail[np]:=qElse - begin toInc (CNT); nq:=cnt;mx[nq]:=mx[p]+1; +a[nq]:=A[q]; -fail[nq]:=Fail[q]; thefail[np]:=nq;fail[q]:=NQ; * whileA[p,c]=q Do $ beginPanax Notoginsenga[p,c]:=nq;p:=Fail[p]; - end; the end; + end; A exit (NP); the end; + - begin $ READLN (n); $ fori:=1to n Doreadln (S[i]); -cnt:=1; root:=1; t:=Root; - fori:=1To Length (s[1]) DoT:=insert (T,ord (s[1, I])- the); the fori:=2To CNT Doans[i]:=Mx[i]; -Fillchar (b,sizeof(b),0);Wuyi fori:=2To CNT DoInc (B[mx[i]); the fori:=2To CNT DoInc (b[i],b[i-1]); - fori:=2To CNT Doans[i]:=Mx[i]; Wu forI:=cnt Downto2 Do - begin About Dec (b[mx[i]]); $q[b[mx[i]]]:=i; - end; - fori:=1to n Do - begin Anow:=root;maxl:=0; +Fillchar (TEM,sizeof(TEM),0); the forj:=1To Length (S[i]) Do - begin $C:=ord (S[i][j])- the; the ifA[now,c]<>0Then begin Now:=a[now,c];inc (MAXL); endElse the begin the while(now<>0) and (a[now,c]=0) Donow:=Fail[now]; the ifnow=0Then BEGIN now:=root;maxl:=0; endElseBegin maxl:=mx[now]+1; now:=A[now,c];end; - end; intem[now]:=Max (TEM[NOW],MAXL); the end; the forJ:=cnt Downto0 Dotem[fail[q[j]]]:=Max (Tem[fail[q[j]]],tem[q[j]]); About forj:=2To CNT Doans[j]:=min (ans[j],tem[j]); the end; thetot:=0; the fori:=2To CNT Do ifAns[i]>tot then tot:=Ans[i]; + writeln (tot); -End.
Compare a bit. Code reduced by One-third, space reduced by nine-tenths ... It's a lot easier to write.
Sam Dafa Good
05/. May
[bzoj2946][poi2000] Common string problem Solving report | suffix automaton