If the pre pointer is not counted, the suffix automata is a dag, which is the precondition for its easy DP.
What the pre pointer returns is that the previous prefix contains the suffix of the substring represented by the change node, and the fail pointer on the AC automaton is similar to the one for the match. I'm not learning so much, I can't see the difference between the fail pointer and the AC automaton, and it's almost the same.
Compared to the dictionary tree and the palindrome tree, suffix automata each node will have multiple parent nodes that can represent multiple seed strings (from the root node to each of its paths is a substring), so the information of the substring can only be recorded in the path, such as length, and the substring says the length of the record step, is the root node to its maximum distance, And the length of a substring is the length of the path that represents the substring, not necessarily the step of a node.
spoj1811
The length of the longest common substring of a two string.
Set up a suffix automaton on string A, match the B string, and if the match fails, follow the failed pointer back to the first matched position to continue matching (looks familiar?). Yes, this is not the process of AC automata ... ), of course, if the root node cannot continue to match, it will only start again. Keep track of length update answers here.
Of course, the suffix array can also be done, the two string splicing up, to find LCP can ... Then the suffix automaton is very fast .... On the Spoj incredibly 60ms over ...
#include <bits/stdc++.h>#defineREP (I,A,B) for (int i=a;i<=b;i++)#defineMS0 (a) memset (A,0,sizeof (a))using namespaceStd;typedefLong Longll;Const intmaxn=2000100;Const intinf=1e9+Ten;structsam{intch[maxn][ -]; intPRE[MAXN],STEP[MAXN]; intLast,tot; voidinit () { last=tot=0; memset (ch[0],-1,sizeof(ch[0])); pre[0]=-1; step[0]=0; } voidAddintc) {c-='a'; intp=last,np=++tot; STEP[NP]=step[p]+1; memset (CH[NP],-1,sizeof(CH[NP])); while(~p&&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=++tot; STEP[NQ]=step[p]+1; memcpy (Ch[nq],ch[q],sizeof(Ch[q])); PRE[NQ]=Pre[q]; PRE[Q]=pre[np]=NQ; while(~p&&ch[p][c]==q) ch[p][c]=nq,p=Pre[p]; } Elsepre[np]=Q; } Last=NP; } intFindChar*s) {intlen=strlen (s); intres=0, tmp=0; intu=0; REP (i,0, len-1){ intc=s[i]-'a'; if(~ch[u][c]) tmp++,u=Ch[u][c]; Else{ while(~u&&ch[u][c]==-1) u=Pre[u]; if(~u) tmp=step[u]+1, u=Ch[u][c]; Elsetmp=0, u=0; } Res=Max (res,tmp); } returnRes; }}; Sam Sam;CharS[MAXN],T[MAXN];voidsolve () {sam.init (); intlen=strlen (s); REP (i,0, len-1) Sam.add (S[i]); printf ("%d\n", Sam.find (t));}intMain () {Freopen ("In.txt","R", stdin); while(~SCANF ("%s%s", S,t)) {Solve (); } return 0;}
View Code
Special topic of suffix automata