Main topic
Give you a trie tree, make \ (s_i\) A string of characters on the path of the point \ (i\) to the root. Request \ (Max_{u\neq v} (LCP (S_u,s_v) +lcs (s_u,s_v)) \)
\ (lcp=\) the longest common prefix,\ (lcs=\) the longest public suffix
\ (1\leq n\leq 200000\), character set is \ (\{0\ldots 300\}\)
Exercises
Let's take a look at this \ (LCP (S_u,s_v) \) How to ask
Generalized suffix automata not. Generalized suffix trees may be possible, but I will not. The generalized suffix array can be. And then I started to promote the semantic suffix array
Generalized suffix array: Similar to suffix array, find the rank of \ (s_i\) and \ (LCP (s_{sa_{}i-1},s_{sa_i}) \)
The implementation is similar to the suffix array, multiplying the information of the two segments \ (2^{i-1}\) into \ (2^i\) . Also save \ ( s_i\) the length of \ ( 2^j\) in the prefix of the length of all strings is the rank of \ (2^j\) in the prefix.
After \ (sa_i\) and \ (rk_i\) , we use two points + Hashiti \ (LCP (s_{sa_{i-1}},s_{sa_i}) \). All of the above-saved rankings for the prefix of \ (2^j\) can be used when the hash value (I wrote a hash on the examination room). The ST table is then used to maintain the minimum interval value. Now we can \ (O (1) \) find out \ (LCP (S_u,s_v) \)
Consider a subtree that is rooted in \ (x\ ), and if \ (u,v\) is in a different subtree of \ (x\) , then \ (LCS (s_u,s_v) =d_x-1\). Here \ (d_x\) is the depth of point \ (x\) , and the root depth is 1.
Because \ (LCS (s_{sa_{i-1}},s_{sa_i}) \geq LCS (S_{sa_x},s_{sa_y}) ~ (X\leq i-1<i\leq y) \), we only use \ (rk_i\) to find the \ (lcp\)of two adjacent points after the keyword is sorted. This can be maintained with a line tree. Then the line tree is merged.
Time complexity:\ (O (n\log n) \)
Code
#include <cstdio>#include <cstring>#include <algorithm>#include <cstdlib>#include <ctime>#include <utility>using namespaceStdtypedef Long Longlltypedefpair<int,int> PII;structlist{intv[200010];intt[200010];intw[200010];inth[200010];intN List () {n=0; memset (H,0,sizeofh); }voidClear () {n=0; memset (H,0,sizeofh); }voidAddintXintYintz) {n++; V[n]=y; T[N]=H[X]; W[n]=z; H[x]=n; }};list L,l2;intf[200010][ -];ll hs[200010][ -];intd[200010];inte[200010];intsa[200010];intrk[200010];intsx[200010];intsy[200010];intb[200010];ll mod=1000000007; ll pw[200010];intht[200010];intst[200010][ -];intlo[200010];intSt:200010];intNintGetmin (intXintY) {intT=lo[y-x+1];returnMin (st[x][t],st[y-(1<<T)+1][t]);}intQueryintXintY) {//x=rk[x];//y=rk[y]; if(x==y)return 0x3fffffff;if(x>y) Swap (x, y);returnGetmin (x+1, y);}namespaceseg{structp {intS,first,last,sz; P () {s=first=last=sz=0; } };intCntintls[4000010];intrs[4000010]; P s[4000010];voidInit () {memset (LS,0,sizeofLS); memset (RS,0,sizeofRS); Cnt=0; } p MT (p a,p b) {if(!A.SZ)returnbif(!B.SZ)returnA P C; C.SZ=A.SZ+B.SZ; C.first=a.first; C.last=b.last; C.s=max (Max (A.S,B.S), query (A.last,b.first));returnC }intInsertintPintXintLintR) {if(!p) p=++cnt;if(L==R) {s[p].sz=1; S[p].first=s[p].last=x;returnP }intMid= (l+r) >>1;if(X<=mid) Ls[p]=insert (Ls[p],x,l,mid);ElseRs[p]=insert (Rs[p],x,mid+1, R); S[P]=MT (S[ls[p]],s[rs[p]);returnP }intMergeintXintY) {if(!x| |! YreturnX+y; Ls[x]=merge (Ls[x],ls[y]); Rs[x]=merge (Rs[x],rs[y]); S[X]=MT (S[ls[x]],s[rs[x]);returnX }};intans=0;voidSolveintx) {Rt[x]=seg::insert (rt[x],rk[x],1, n);intI for(I=l.h[x];i;i=l.t[i]) {Solve (l.v[i]); Rt[x]=seg::merge (Rt[x],rt[l.v[i]); }if(seg::s[rt[x]].sz>1) Ans=max (Ans,d[x]-1+SEG::S[RT[X]].S);}intMain () {memset (RT,0,sizeofRT); Seg::init ();intI,j,x,y; pw[0]=311; for(i=1; i<= -; i++) Pw[i]=pw[i-1]*pw[i-1]%mod; Freopen ("Recollection.in","R", stdin); Freopen ("Recollection.out","W", stdout); Memset (F,0,sizeoff); scanf"%d", &n); d[1]=1; e[1]=310; hs[1][0]=310; for(i=2; i<=n;i++) {scanf ("%d%d", &x,&y); L.add (X,i,y); f[i][0]=x; D[I]=D[X]+1; E[i]=y+1; hs[i][0]=e[i]; for(j=1; j<= -; j + +) {F[i][j]=f[f[i][j-1]][j-1]; Hs[i][j]= (hs[f[i][j-1]][j-1]*pw[j-1]+hs[i][j-1])%mod; } }intsz=310, K,o; for(i=1; i<=sz;i++) b[i]=0; for(i=1; i<=n;i++) b[sx[i]=e[i]]++; for(i=2; i<=sz;i++) B[i]+=b[i-1]; for(i=n;i>=1; i--) sa[b[sx[i]]--]=i; for(j=1;(1<<J) <=n;j++) {l2.clear (); k=0; for(i=1; i<=n;i++)if(D[sa[i]]> (1<< (J-1))) L2.add (f[sa[i]][j-1],sa[i],0); for(i=1; i<=n;i++) for(O=l2.h[sa[i]];o;o=l2.t[o]) sy[++k]=l2.v[o]; for(i=1; i<=n;i++)if(D[i]<= (1<< (J-1))) Sy[++k]=i; for(i=1; i<=sz;i++) b[i]=0; for(i=1; i<=n;i++) b[sx[sy[i]]]++; for(i=2; i<=sz;i++) B[i]+=b[i-1]; for(i=n;i>=1; i--) Sa[b[sx[sy[i]]]--]=sy[i]; k=0; Swap (SX,SY); for(i=1; i<=n;i++)if(i!=1&&sy[sa[i]]==sy[sa[i-1]]&& ((d[sa[i]]<= (1<< (J-1)) &&d[sa[i-1]]<= (1<< (J-1)))|| (D[sa[i]]> (1<< (J-1)) &&d[sa[i-1]]> (1<< (J-1)) &&sy[f[sa[i]][j-1]]==sy[f[sa[i-1]][j-1]])) sx[sa[i]]=k;ElseSx[sa[i]]=++k;if(k>=n) Break; Sz=k; } for(i=1; i<=n;i++) rk[sa[i]]=i; ht[0]=0; for(i=2; i<=n;i++) {X=sa[i-1]; Y=sa[i];intnow=0; for(j= -; j>=0; j--)if(D[x]-1>= (1<<J) &&d[y]-1>= (1<<J) (&&hs[x][j]==hs[y][j]) {now+= (1<<J); X=F[X][J]; Y=F[Y][J]; } Ht[i]=now; } for(i=1; i<=n;i++) st[i][0]=ht[i]; for(j=1; j<= -; j + +) for(i=1; i+ (1<<J)-1<=n;i++) St[i][j]=min (st[i][j-1],st[i+ (1<< (J-1))][j-1]); lo[1]=0; for(i=2; i<=n;i++) lo[i]=lo[i/2]+1; Solve1); printf"%d\n", ans);return 0;}
"XSY1551" Events generalized suffix array segment tree merging