Topic Links: HDU_5507_GT and strings
Test instructions: give n string and q query, each query to two number x, Y, ask whether 1.x is a sub-sequence of Y, 2.x is a substring of y, is output 1, otherwise output 0, each query output 2 digits
Exercises
For sub-sequences, the naïve approach, the complexity of each query for Max (Str[x],str[y]), the topic seems to have a data card this practice, anyway, will be T, the positive solution should be to build a sequence automaton, first of all the strings stored continuously, with the array to save each string position, and then Dp[i] [j] denotes the position of the next character of the first character, which can be as complex as min (Str[x],str[y]) when asked. 、
For the substring, you can use AC automata to pre-processing, sub-string inquiry is a bit special, not the general walk in the tree, but for each node to find, and then use map to record the relationship, but in the inquiry also has an optimization, do not add this optimization will T, add a moment to become 170+ms, specific look at the code.
1#include <bits/stdc++.h>2 #defineF (I,A,B) for (int i=a;i<=b;i++)3 using namespacestd;4typedef pair<int,int>P;5 6 Const intn=1e5+7;7 intt,n,m,l[n],r[n],loc[n],dp[n][ -],q[n][2],ans[n][2];8 CharStr[n];9Map<p,int>OK;Ten Const intac_n=n,tyn= -;//number multiplied by string length, number of types One structac_automation{ A intTr[ac_n][tyn],cnt[ac_n],q[ac_n],fail[ac_n],tot; -InlineintGetIDCharx) {returnX-'a';} - voidNW () {cnt[++tot]=0, fail[tot]=0; memset (Tr[tot],0,sizeof(Tr[tot]));} the voidInit () {tot=-1, fail[0]=-1, NW ();} - voidInsertintLintRintx=0){ - for(inti=l,w;i<=r;x=tr[x][w],loc[i]=x,i++) - if(!tr[x][w=getid (Str[i])) NW (), tr[x][w]=tot; +cnt[x]++;//end of string Mark - } + voidBuildintHead=1,intTail=0){ A for(intI=0; i<tyn;i++)if(tr[0][i]) q[++tail]=tr[0][i]; at 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]; - Elsetr[x][i]=Tr[fail[x]][i]; - } - voidAskintLintR) - { inF (I,l,r) for(intP=loc[i];p; p=Fail[p]) - if(Cnt[p]) ok[p (P,loc[r])]=1; to Else if(Fail[p]&&!cnt[fail[p]]) fail[p]=fail[fail[p];//deciding whether to optimize for T + } - }ac; the * voidWork1 () $ {Panax NotoginsengF (I,0, -) dp[r[n]+1][i]=n;//creating a "subsequence automaton" - for(inti=r[n];i>=1; i--) F (J,0, -) the if(str[i]==j+'a') dp[i][j]=i; + Elsedp[i][j]=dp[i+1][j]; AF (I,1, M) the { + intx=q[i][0],y=q[i][1]; - if(R[x]-l[x]>r[y]-l[y]) ans[i][0]=0; $ Else $ { -ans[i][0]=1; - for(intj=l[x],p=l[y];j<=r[x];j++,p++) the { -p=dp[p][str[j]-'a'];Wuyi if(P>r[y]) {ans[i][0]=0; Break;} the } - } Wu } - } About $ voidWork2 () - { - ac.init (), Ok.clear (); -F (I,1, N) Ac.insert (L[i],r[i]); A ac.build (); +F (I,1, N) Ac.ask (L[i],r[i]); theF (I,1, m) ans[i][1]=ok[p (loc[r[q[i][0]]],loc[r[q[i][1]]])]; - } $ the intMain () the { thescanf"%d",&t); the while(t--) - { inscanf"%d%d",&n,&m); the intEd=1; theF (I,1, N) About { thescanf"%s", str+ed); the intLen=strlen (str+ed); thel[i]=ed,r[i]=ed+len-1, ed=r[i]+1; + } -F (I,1, m) scanf ("%d%d", &q[i][0],&q[i][1]); the Work1 (), Work2 ();BayiF (I,1, m) printf ("%d%d", ans[i][0],ans[i][1]); thePuts""); the } - return 0; -}
View Code
HDU_5507_GT and Strings (AC automata)