[NOI2011] Ali typewriter ac automaton +dfs sequence + tree-like array

Source: Internet
Author: User

[NOI2011] Ali's typewriter description

Ali like to collect all kinds of strange things, he recently Amoy to an old-fashioned typewriter. There are only 28 keys on the typewriter, with 26 lowercase English letters and ' B ' and ' P ' two letters printed respectively.
The ALI study found that the typewriter worked like this:

L Enter lowercase letters and the letter is added to a groove in the typewriter (the letter is added to the end of the groove).
L PRESS the ' B ' button and the last letter in the typewriter groove disappears.
L PRESS the ' P ' button and the typewriter will print all the existing letters in the groove and wrap them on the paper, but the letters in the groove will not disappear.
For example, Ali input APAPBBP, the characters printed on the paper are as follows:

A

Aa

a b

We numbered the printed string on the paper from 1 onwards to N. Typewriter has a very interesting function, in the typewriter hidden a small keyboard with a number, on the keypad input two number (x, y) (where 1≤x,y≤n), the typewriter will show the first x printed string in the first number of printed strings in the occurrence of how many times.
Ali found this feature was very excited, he wanted to write a program to complete the same function, can you help him?

Input

The first line of input contains a string that gives all the characters of the beaver input in the order of Ali input. The second line contains an integer m, which indicates the number of queries. The next M-line describes all the queries entered by the keypad. Where line I contains two integers x, y, which indicates that I inquired for (x, y).

Output

Output m line, where line I contains an integer representing the answer to the I query.

Sample InputAPAPBBP 3 1 2 1 3 2 3Sample Output2 1 0HINT 1<=n<=10^51<=m<=10^5 Input Total length <=10^5

The puzzle: First build the Fail tree, and then for a query a B, we can convert it to a subtree (here, the subtree-fail tree), how many nodes in the word b appeared, so we naturally think to use offline processing to engage. That is, when DFS traverses the fail tree, separately records from the above query to the point and from the following back to the point, how many nodes have appeared in B, the difference between the two is the answer we want, we just need to store the inquiry in the form of a linked list to a can be.

But we have found a problem, for a certain node, it may exist in many words, then we search this point will be the number of these words appear all +1, how to do?

We may as well analyze the nature of the AC automata, for all words containing node x, their end point must be in the X-root of the China (here subtree refers to AC automata). It is observed that these end points must be a continuous interval in the DFS sequence of the AC automaton (no other end points in the middle). Using this property, we can find the corresponding interval for each node x, then the entire interval +1, which can be implemented in a tree array.

(The above are personal ideas, maybe trouble, but it turns out to be AC)

The disgusting thing about this is that: 1. For an end point, you need to know its number in the AC automaton, know its number in the inquiry, and know its number in the DFS sequence, which is especially easy to confuse. 2.DFS is going to be done two times, once on the AC automaton, again on the fail tree. 3. The fail tree we began to find was from the son pointing to the father, and we are going to build another tree again. 4. An end point may correspond to multiple words.

#include <cstdio>#include<cstring>#include<iostream>#include<queue>using namespacestd;Const intmaxn=100010;structnode{intch[ -],fail,l,r,cnt;} P[MAXN];CharSTR[MAXN];intSTA[MAXN],TP,S[MAXN],POS[MAXN];intN,tot,len,sum,now;intT1[MAXN],N1[MAXN],H1[MAXN],ANS[MAXN],N2[MAXN],H2[MAXN];intTree[maxn];queue<int>Q;voidUpdata (intXintv) {     for(intI=x;i<=sum;i+=i&-i) tree[i]+=v;}intQueryintx) {    inti,ret=0;  for(i=x;i;i-=i&-i) ret+=Tree[i]; returnret;}voidDFS1 (intX//traversing AC automata{P[X].L=p[x].r=now;//If this point is the end point, then now is the order of the point in the DFS ordernow+=p[x].cnt;//[L,r] is the interval of words affected by this point     for(intI=0;i< -; i++)    {        if(P[x].ch[i]) {DFS1 (p[x].ch[i]); P[X].R=Max (P[X].R,P[P[X].CH[I]].R); }    }}voidbuild () {inti,j,u,t; Q.push (1);  while(!Q.empty ()) {u=Q.front (), Q.pop ();  for(i=0;i< -; i++)//don't change your son with fail here, because you want DFS.        {            if(!p[u].ch[i])Continue;            Q.push (P[u].ch[i]); T=P[u].fail;  while(!p[t].ch[i]&&t) t=P[t].fail; if(t) p[p[u].ch[i]].fail=P[t].ch[i]; ElseP[p[u].ch[i]].fail=1; }    }}voidDfsintX//traverse the Fail tree{    inti;  for(i=h1[x];i;i=N1[i]) {Ans[i]-=query (P[T1[I]].L); } updata (P[X].L,1); Updata (P[X].R+1,-1);  for(i=h2[x];i;i=N2[i])    {DFS (i); }     for(I=h1[x];i;i=n1[i])//two times the difference is the answer, just a little bit.{Ans[i]+=query (P[T1[I]].L); }}intMain () {scanf ("%s%d",str,&N); Len=strlen (str); inti,j,k,u,t,a,b; U=sta[++tp]=1; Tot=1;  for(i=0; i<len;i++)//with the stack, the input is actually very simple.    {        if(str[i]=='B') u=sta[--TP]; Else if(str[i]=='P') p[u].cnt++,pos[++sum]=u; Else        {            if(!p[u].ch[str[i]-'a']) p[u].ch[str[i]-'a']=++tot; U=p[u].ch[str[i]-'a']; sta[++tp]=u; }    }     for(i=1; i<=n;i++) {scanf ("%d%d", &a,&b);//Store the query on the A nodet1[i]=Pos[b]; N1[i]=H1[pos[a]]; H1[pos[a]]=i;    } build (); now=1; DFS1 (1);  for(i=2; i<=tot;i++)//Rebuilding the Fail tree{N2[i]=H2[p[i].fail]; H2[p[i].fail]=i; } DFS (1);  for(i=1; i<=n;i++) printf ("%d\n", Ans[i]); return 0;}

[NOI2011] Ali typewriter ac automaton +dfs sequence + tree-like 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.