Main topic: The initial string is empty, first given a series of sequence of operations, there are three kinds of operations:
1. Add a character at the end
2. Delete a character at the end
3. Print the current string
And then asked several times the X-printed string in the first Y-printed string appeared several times
Card for a long time ... It's not so deep about AC automata, is it? Qaq
The fail tree is not very difficult to think at least after cutting off 3172 with an AC automaton.
First, the AC automata. Note Because of the special structure of this string, we don't have to insert the trie tree with every string printed.
Let now start with the current pointer as root consider three operations
Add a character at the end, create a new child node (if it is not new), enter the child node
Delete a character at the end to return to the Father node
Prints the current string, with the current node tag being the number of strings
Then the query x appears in Y several times is the query y how many nodes along the fail pointer can find X (AC automaton basic operation)
So we're thinking backwards. How many nodes along the fail pointer can find x in query y how many y nodes can be found along the reverse fail pointer
The fail pointer has no ring, only one out of each node, and then it's obviously a tree. The node to which the fail pointer is located along the opposite end is the subtree of x.
So we can go along the reverse of the fail pointer to the DFS sequence x is located in the sub-tree is DFS in the corresponding interval we want to query the x corresponding to the interval of how many y
Want advanced data structure can wash and sleep
We can do this.
For each y:
We have a query about Y in the adjacency table and then insert Y all nodes in the Dfs order into the tree array, and then for each inquiry about Y on the tree array.
So here's the question: Isn't it tle?
The answer is no, because of the specificity of the problem, the tree array can reach O (NLOGN)
After we find out the DFS sequence we come back to consider these sequence of operations
Add a character at the end of a character to add a node to the tree array
Delete a character--delete a character at the end of a node from a tree-like array
Printing the current string, processing inquiries
And then it got out. 1A I'm drunk, too.
#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define M 100100using namespace std;struct trie{trie *son[26],*fail;vector<trie*> next;int ed,pos; void* operator new (size_t);} *root=new trie,mempool[m],*c=mempool;struct abcd{int To,pos,next;} Table[m];int head[m],tot;int N,m,ans[m];char s[m];int start[m],end[m],cnt;int c[m];void* Trie:: operator new (size_t) { return C + +;} void Add (int x,int y,int z) {Table[++tot].to=y;table[tot].pos=z;table[tot].next=head[x];head[x]=tot;} void Update (int x,int y) {for (; x<=cnt;x+=x&-x) c[x]+=y;} int Get_ans (int x) {int re=0;for (; x;x-=x&-x) Re+=c[x];return re;} void Build_tree () {int i;static trie* stack[m];static int top;stack[++top]=root;for (i=1;s[i];i++) {switch (S[i]) {case ' B ': Stack[top--]=0x0;break;case ' P ': stack[top]->ed=++n;break;default:if (!stack[top]->son[s[i]-' a ']) stack[ top]->son[s[i]-' A ']=new trie;stack[++top]=stack[top-1]->son[s[i]-' a '];break;}} Static Trie *q[m];static int r,h;for (i=0;i<26;i++) if (Root->son[i]) {Root->son[i]->fail=root;root->next.push_ Back (Q[++r]=root->son[i]);} while (r!=h) {Trie *p=q[++h];for (i=0;i<26;i++) if (P->son[i]) {Trie *temp=p->fail;while (temp!=root&& !temp->son[i]) temp=temp->fail;if (Temp->son[i]) temp=temp->son[i];p->son[i]->fail=temp;temp- >next.push_back (Q[++r]=p->son[i]);}} void DFS (Trie *p) {vector<trie*>::iterator it;p->pos=++cnt;if (p->ed) start[p->ed]=cnt; for (it=p-> Next.begin (); It!=p->next.end (); it++) DFS (*it); if (p->ed) end[p->ed]=cnt;} void Solve () {int i,j;static trie* stack[m];static int top;stack[++top]=root;for (j=1;s[j];j++) {switch (S[j]) {case ' B ': Update (stack[top]->pos,-1); Stack[top--]=0x0;break;case ' P ': for (I=head[stack[top]->ed];i;i=table[i].next) Ans[table[i].pos]=get_ans (End[table[i].to])-get_ans (start[table[i].to]-1); break;default:stack[++top]=stack[ Top-1]->son[s[j]-' a ']; Update (stack[top]->pos,1); break;}}} int MAIn () {int i,x,y;scanf ("%s", s+1); Build_tree ();D FS (root), cin>>m;for (i=1;i<=m;i++) {scanf ("%d%d", &x,&y); ADD (y,x,i);} Solve (); for (i=1;i<=m;i++) printf ("%d\n", Ans[i]);}
Bzoj 2434 NOI2011 Ali typewriter fail tree + tree-like array