"The main topic"
The longest common substring of a two string.
Ideas
Establish a suffix automaton on the first string, and a second string to match. CNT records the length of the current longest common substring, while RET records the answer.
P represents the position pointer, initially in the RT position.
For one s[i of the second string], if there is currently s[i] child, then cnt+1, continue to move backwards, otherwise along the pre pointer. If the pre pointer returns to 0, then p back to rt,cnt is emptied to 0, otherwise if the middle has a little s[i] child, cnt=step[]+1.
Why cnt=step[]+1? Do not forget that the essence of the suffix automaton is to maintain the suffix, running along the pre pointer to a smaller length of the suffix to move, a position represented by the suffix of the longest length of step[], plus s[i], that is step[]+1.
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5#include <cmath>6 using namespacestd;7 Const intmaxn=100000+5;8 intN;9 Charstr[2][MAXN];Ten structSAM One { A intstep[maxn*2],pre[maxn*2],next[maxn*2][ -]; - intTot,last; -InlineintNewNode (intCNT) the { -step[++tot]=CNT; -pre[tot]=0; - for(intI=0;i< -; i++) next[tot][i]=0; + returntot; - } + AInlinevoidExtendintx) at { - intp=Last ; - intNp=newnode (step[p]+1); - while(P &&!next[p][x]) next[p][x]=np,p=Pre[p]; - if(!p) pre[np]=1; - Else in { - intq=Next[p][x]; to if(step[q]==step[p]+1) pre[np]=Q; + Else - { the intNq=newnode (step[p]+1); * for(intI=0;i< -; i++) next[nq][i]=Next[q][i]; $pre[nq]=Pre[q];Panax Notoginsengpre[q]=pre[np]=NQ; - while(p&&next[p][x]==q) next[p][x]=nq,p=Pre[p]; the } + A } thelast=NP; + } - $InlinevoidClear () $ { - inttot=0; -last=NewNode (tot); the } - WuyiInlineintQuery () the { - intret=0, cnt=0; Wu intp=1; - for(intI=0; str[1][i];i++) About { $ intindex=str[1][i]-'a'; - if(Next[p][index]) p=next[p][index],cnt++; - Else - { A while(P &&!next[p][index]) p=Pre[p]; + if(!p) p=1, cnt=0; the Elsecnt=step[p]+1, p=Next[p][index]; - /*since the string that is returned along the pre is the suffix of the current string, the first child with index is the longest-satisfying suffix, which is the length of step+1*/ $ } theret=Max (ret,cnt); the } the returnret; the } - }suf; in the voidInit () the { Aboutscanf"%d",&n); thescanf"%s", str[0]); the intLen=strlen (str[0]); the suf.clear (); + for(intI=0; i<len;i++) Suf.extend (str[0][i]-'a'); -scanf"%s", str[1]); the }Bayi the intMain () the { - init (); -printf"%d", Suf. Query ()); the return 0; the}
"SAM" codevs3160-the longest common child string