[NOI2011] [bzoj2434] Ali typewriter [AC automaton +dfs Sequence +fail tree + Tree Array]

Source: Internet
Author: User

Surface

Portal

The most violent of the body

The most violent method: run through all the strings that ask for the KMP and then output

Just a little bit of optimization: Save all the questions, merge the template strings the same, find next and match them.

But there's no difference between the two approaches, they're violent.

Not so violent.

We set up an AC automaton for all the strings, sort the inquiry according to $y$, then run on the AC automaton, and update the answer with each fail.

This can get 70 points, but the time limit will still be $o\left (n^2\right) $ about

Ingenious optimization

In this problem, all the template strings and text strings are in the AC automata.

So what is actually being asked for in the title?

is how many x strings are the suffix of a prefix of the y string.

So, does the AC automaton have a structure that satisfies such a search?

Yes, that's the fail pointer.

A fail pointer to one of the prefixes on the trie, pointing to the node that is the longest suffix of it, and jumping along the fail pointer from a prefix until the root node, where all nodes represent prefixes that are suffixes of this prefix

That is, we look at the fail pointer as a tree edge and extract the "Fail Tree" (not to confuse the next tree with KMP), so we can turn the question into this:

Mark the nodes that represent all prefixes of the Y string, so the number of tokens in the subtree of the nodes that represent the X-strings is the answer to this query.

Maintenance number and can be done together with the DFS sequence on the fail tree and the tree array

Positive solution

There is a repetition in the process: each time we need to zero the tree array, and then re-insert the new y-string prefix node-even if we use the method of sorting Y will be tle

But there is a problem in this process: some points will go in and out many times, not efficient, we need to find a way to make each AC automaton point only in and out of the tree-like array once

So who can meet this requirement?

Or DFS sequence, just the DFS sequence on the original trie tree.

We order the input query according to the DFS sequence of y string on trie tree, join, delete

The total time efficiency of this method is only $o\left (Nlogn\right) $, because the DFS sequence traversal allows each point to enter one time away.

So this problem is done.

Code

The map of the subject is very many, and very complicated, there are many repetitive meaning of things, when commissioning must be careful

Variable name is a bit messy, please forgive me

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#define Rank Deep_dark_fantasyusing namespaceStdstructnode{intfail,fa,son[ -]; vector<int>num; Node () {fail=fa=0; Memset (son,0,sizeof(son)); Num.clear ();}} a[100010];intCnt,tot;intdfn[100010],clk,end[100010],tmplca,pre[100010],rank[100010];//DFN is the trie tree DFS sequence, rank is the reflection of DFN//end is the node number of each string on the trie tree//pre indicates that the LCA,TMPLCA is a helper variable that is maintained by the string transfer of the DFS sequence of I to the i+1 string.structedge{intTo,next;} e[100010];intcnte,first[100010];inline voidAddedge (intUintV) {e[++cnte]= (edge) {v,first[u]};first[u]=cnte;}inline voidAddCharS[]) {intLen=strlen (s), cur=0I for(i=0; i<len;i++) {if(s[i]==' P ') {A[cur].num.push_back (++tot);Continue;}if(s[i]==' B ') {CUR=A[CUR].FA;Continue;}if(!a[cur].son[s[i]-' A ']) a[cur].son[s[i]-' A ']=++cnt; a[a[cur].son[s[i]-' A ']].fa=cur;cur=a[cur].son[s[i]-' A ']; }}voidGETDFN (intu) {intI,v,len=a[u].num.size (); for(i=0; i<len;i++) {dfn[++clk]=a[u].num[i];        RANK[A[U].NUM[I]]=CLK;        End[a[u].num[i]]=u;    Pre[clk]=tmplca;tmplca=u; } for(i=0;i< -; i++) {v=a[u].son[i];if(!V)Continue;    GETDFN (v); tmplca=u; }}intq[100010];voidGetfail () {intHead=0, tail=0, I,u,v; for(i=0;i< -; i++) {if(!a[0].son[i])Continue; a[a[0].son[i]].fail=0; q[tail++]=a[0].son[i]; } while(Head<tail) {u=q[head++]; for(i=0;i< -; i++) {v=a[u].son[i];if(v) a[v].fail=a[a[u].fail].son[i],q[tail++]=v;ElseA[u].son[i]=a[a[u].fail].son[i]; }} memset (First,-1,sizeof(first)); for(i=1; i<=cnt;i++) Addedge (a[i].fail,i);}Chars[100010];intQ;structquery{intX,y,num,ans;} qq[100010];BOOLCMP (Query L,query R) {returnRANK[L.Y]&LT;RANK[R.Y];}BOOLCMP2 (Query L,query R) {returnL.num<r.num;}intnow=0, Tmpnow;structtree{//tree-like array    intx[100010]; Tree () {memset (x,0,sizeof(x));}intLowbit (intPOS) {returnpos& (-pos);}voidChangeintPosintType) { for(intI=pos;i<=cnt+1; I+=lowbit (i)) X[i]+=type; }intAskintPOS) {intRe=0; for(intI=pos;i>0; I-=lowbit (i)) re+=x[i];returnRe }}t;intfaildfn[100010],failclk=0, le[100010],ri[100010];//FAILDFN is the DFS order on the fail tree, and Le and RI are the left and right intervals of a node on a tree arrayvoidGET_FAIL_DFN (intu) {intI,V;FAILDFN[U]=++FAILCLK;LE[U]=FAILCLK; for(I=first[u];~i;i=e[i].next)        {v=e[i].to;    GET_FAIL_DFN (v); } RI[U]=FAILCLK;}intMain () {scanf ("%s", s);intI,j,x,y,xx; Add (s); GETDFN (0); Getfail (); GET_FAIL_DFN (0); scanf"%d", &q); for(i=1; i<=q;i++) scanf ("%d%d", &qq[i].x,&qq[i].y), qq[i].num=i; Sort (QQ+1, Qq+q+1, CMP);//Sortj=1; for(i=1; i<=tot;i++) {y=dfn[i];tmpnow=end[y]; while(Now!=pre[i]) {T.change (Faildfn[now],-1); NOW=A[NOW].FA; } while(Tmpnow!=now) {T.change (Faildfn[tmpnow],1); TMPNOW=A[TMPNOW].FA; }//INSERT, delete nodeNow=end[y]; while(qq[j].y==y) {//Handling inquiriesXx=end[qq[j].x]; Qq[j].ans=t.ask (Ri[xx])-t.ask (Le[xx]-1);        j + +; }} sort (QQ+1, Qq+q+1, CMP2); for(i=1; i<=q;i++) printf ("%d\n", Qq[i].ans);}

[NOI2011] [bzoj2434] Ali typewriter [AC automaton +dfs Sequence +fail tree + Tree Array]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.