Title Link: UVALive-4811 Growing Strings
Test instructions
Give you n a string, ask how many strings you can select, so that s[i] is a substring of s[i+1].
Exercises
All strings are inserted into the AC automaton first, and all strings are sorted by length, apparently dp[i]=max{dp[j]}+1, where s[j] is a substring of s[i]. And then it's over.
1#include <bits/stdc++.h>2 #defineMST (A, B) memset (A,b,sizeof (a))3 #defineF (I,A,B) for (int i= (a); i<= (b); ++i)4 using namespacestd;5 6 Const intac_n=1e6+7, tyn= -;7 intN,dp[ac_n],ed,ans;8 CharS[ac_n];9 structStrTen { One intL,len; A BOOL operator< (ConstStr &b)Const{returnlen<B.len;} - }str[ac_n]; - the structac_automation{ - intTr[ac_n][tyn],cnt[ac_n],q[ac_n],fail[ac_n],tot; -InlineintGetIDCharx) {returnX-'a';} - voidNW () {cnt[++tot]=0, fail[tot]=0; MST (Tr[tot],0);} + voidInit () {tot=-1, fail[0]=-1, NW ();} - voidInsertChar*s,intLenintIdxintx=0){ + for(intI=0, w;i<len;x=tr[x][w],i++) A if(!tr[x][w=getid (S[i])) NW (), tr[x][w]=tot; atcnt[x]=idx; - } - voidBuildintHead=1,intTail=0){ - for(intI=0; i<tyn;i++)if(tr[0][i]) q[++tail]=tr[0][i]; - while(Head<=tail) for(intX=q[head++],i=0; i<tyn;i++) - if(Tr[x][i]) fail[tr[x][i]]=tr[fail[x]][i],q[++tail]=Tr[x][i]; in Elsetr[x][i]=Tr[fail[x]][i]; - } to intAskChar*s,intLint&ans) { + for(intx=0, i=0, w,j;i<l;i++){ -x=tr[x][w=GetID (S[i]); the for(J=x;j;j=fail[j])if(Cnt[j]) ans=Max (Ans,dp[cnt[j]]); * } $ returnans;Panax Notoginseng } - }ac; the + intMain () { A while(SCANF ("%d",&N), N) the { +Ed=0, ans=1; -F (I,1, N) $ { $scanf"%s", s+ed); -Str[i]=str{ed, (int) strlen (s+ed)}; -ed+=Str[i].len; the } -Sort (str+1, str+1+n);Wuyi ac.init (); theF (I,1, N) Ac.insert (s+str[i].l,str[i].len,i); -Ac.build (), dp[1]=1; WuF (I,2, N) - { Aboutdp[i]=0, Ac.ask (s+str[i].l,str[i].len,dp[i]); $dp[i]++,ans=Max (ans,dp[i]); - } -printf"%d\n", ans); - } A return 0; +}
View Code
UVALive-4811 growing Strings (AC automaton +DP)