[BZOJ2434] [Noi2011] Ali's typewriter
Question 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
Ab
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.
Input example
APAPBBP 3 1 2 1 3 2 3
Output example
2 1 0
Data size and conventions
1<=n<=10^5
1<=m<=10^5
Input total length <=10^5
Exercises
First, build an AC automaton to build the Trie tree and the Fail tree.
It is not difficult to think of a violent: for each inquiry (x, y), from each node in the Trie tree y-root along the Fail side, the number of paths that can reach the X-node is the answer.
Think of a different angle: for the query (x, y), in the Fail tree, the number of nodes that meet the "condition" in the subtree with node x as the root. A node satisfies "condition" when and only if the node is on y-root in the Trie tree.
Now that you are dealing with subtree problems, you can turn them into sequence problems with the DFS sequence.
Ask for the DFS sequence of the Fail tree, re-traverse the AC automaton, and when you encounter the node U on the Trie tree, add 1 to the DFS sequence located at L[u] and subtract 1 from the position of the node U up-l[u]. Offline processing of each query, when the current node is Y, all (xi, y) of the query disposed of, the answer is the interval [l[xi], R[xi] and.
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <stack > #include <vector> #include <queue> #include <cstring> #include <string> #include <map > #include <set>using namespace std;const int buffersize = 1 << 16;char buffer[buffersize], *head, *TAIL;INL ine Char Getchar () {if (Head = = tail) {int L = fread (buffer, 1, buffersize, stdin); Tail = (Head = buffer) + L; } return *head++;} int read () {int x = 0, f = 1; char c = Getchar (); while (!isdigit (c)) {if (c = = '-') f =-1; c = Getchar ();} while (IsDigit (c)) {x = x * + C-' 0 '; c = Getchar ();} return x * f;} #define MAXN 100010#define maxs 26int N, Q, ANS[MAXN], POS[MAXN], Cnt;char s[maxn];int m, Head[maxn], NEXT[MAXN], TO[MAXN] void Addedge (int a, int b) {//printf ("%d,%d\n", A, b); to[++m] = b; next[m] = Head[a]; Head[a] = M;return;} int ToT = 1, F[MAXN], FA[MAXN], Ch[maxn][maxs], Q[MAXN], HD, tl;voidGetfail () {HD = TL = 0; f[1] = 1;for (int i = 0; i < maxs; i++) if (Ch[1][i]) {int u = ch[1][i];f[u] = 1; Q[++TL] = u; Addedge (1, u);} while (HD < TL) {int r = q[++hd];for (int i = 0; i < maxs; i++) if (Ch[r][i]) {int u = ch[r][i];int j = F[r];while (J &G T 1 &&!ch[j][i]) j = f[j];f[u] = ch[j][i]? Ch[j][i]: 1; Addedge (F[u], u); Q[++TL] = u;}} return;} int tot, L[MAXN], r[maxn];void build (int u) {l[u] = ++tot;for (int e = head[u]; e; e = next[e]) build (To[e]); R[u] = Tot;return;} int HEADQ[MAXN], NEXTQ[MAXN], qx[maxn];int c[maxn];void Add (int x, int v) {for (; x <= tot; x + = x & x) c[x] + = V; return; }int sum (int x) {int res = 0; for (; x; x = x & x) Res + = C[x]; return res;} int main () {//freopen ("data.in", "R", stdin),//freopen ("Data.out", "w", stdout), char TC = Getchar (), while (!isalpha (TC)) TC = Getchar (); int u = 1;while (Isalpha (TC)) {if (' a ' <= TC && TC <= ' z ') {int d = TC-' a '; if (!ch[u][d]) ch[u ][d] = ++tot, fa[ch[u][d]] = U;u = Ch[u][d];} if (TC= = ' P ') pos[++cnt] = u;if (tc = = ' B ' && fa[u]) u = fa[u]; S[++n] = TC;TC = Getchar ();} printf ("%d\n", ToT);//for (int i = 1; I <= cnt; i++) printf ("%d", pos[i]); Putchar (' \ n '); Getfail (); Build (1); q = read (); for (int i = 1; I <= Q; i++) {int x = Pos[read ()], y = Pos[read ()];nextq[i] = Headq[y]; Headq[y] = i ; Qx[i] = x;} U = 1;for (int i = 1; I <= n; i++) {if (' a ' <= s[i] && s[i] <= ' z ') u = ch[u][s[i]-' A '], add (L[u], 1); if (s[ I] = = ' B ' && fa[u]) Add (L[u],-1), U = fa[u];if (S[i] = = ' P ') for (int i = headq[u]; i; i = Nextq[i]) ans[i] = SUM (r[ Qx[i]])-sum (l[qx[i]]-1);} for (int i = 1; I <= Q; i++) printf ("%d\n", Ans[i]); return 0;}
[BZOJ2434] [Noi2011] Ali's typewriter