2434: [Noi2011] Ali's typewriter time limit: ten Sec Memory Limit: + MB
Submit: 2119 Solved: 1225
[Submit] [Status] [Discuss] 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.
Sample InputApapbbp
3
1 2
1 3
2 3
Sample Output2
1
0HINT
1<=n<=10^5
1<=m<=10^5
Input total length <=10^5
Source
Trie
AC automatic Machine + Fail Tree + tree-like array , thinking good question
You can first build a trie tree for all strings within the complexity of O (n).
The BFS then evaluates the fail array.
The string x is the suffix of the string y, and only if Y can go through the fail edge to X. Then X is a substring of y, and only if the ancestors of y in the trie tree can go through the fail edge to X. So for an inquiry (x, y), it is equivalent to asking Y how many ancestors on the trie tree can go through the fail side to X.
Found that the fail side of the reverse form a tree structure, called the tree is the fail tree.
Then ask how many points in the subtree that are equivalent to X are the ancestors of Y on the trie tree.
Consider the offline approach, sort by the Dfs sequence on Y on trie, and then use a tree-like array to maintain information on the DFS sequence of the fail tree.
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring > #include <algorithm> #include <queue> #define F (I,j,n) for (int. i=j;i<=n;i++) #define D (i,j,n) for (int i=j;i>=n;i--) #define LL long long#define maxn 100005using namespace Std;int n,now,cnt,tot,cnte;int a[maxn][26],fa[ Maxn],fail[maxn],id[maxn],pos[maxn];int L[maxn],r[maxn],sum[maxn],head[maxn],ans[maxn];char S[maxn];queue<int > q;struct data{int x, y;} P[maxn];struct edge_type{int Next,to;} E[maxn];inline int read () {int X=0,f=1;char ch=getchar (); while (ch< ' 0 ' | | Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} inline void Add_edge (int x,int y) {e[++cnte]= (edge_type) {head[x],y};head[x]=cnte;} void Getfail () {Q.push (1); while (!q.empty ()) {int X=q.front (); Q.pop (); F (i,0,25) if (A[x][i]) {int y=a[x][i],j=fail[x];while (j&&!a[j][i]) J=fail[j];fail[y]=j?a[j][i]:1;q.push (y);}} void Dfs (int x) {L[X]=++tot;for (int i=head[x];i;i=e[i].next) DFS (e[i].to); r[x]=tot;} void Add (int x,int y) {for (; x<=cnt;x+= (x& (x))) Sum[x]+=y;} int query (int x) {int ret=0;for (; x;x-= (x& (x))) Ret+=sum[x];return ret;} void solve (int x) {Add (l[x],1), for (int i=head[id[x]];i;i=e[i].next) {int t=e[i].to;ans[i]=query (r[pos[t]])-query (l[ POS[T]]-1);} F (i,0,25) if (A[x][i]) solve (a[x][i]); add (l[x],-1);} int main () {scanf ("%s", s+1); int Len=strlen (s+1); now=cnt=1; F (I,1,len) {if (s[i]== ' B ') now=fa[now];else if (s[i]== ' P ') id[now]=++tot,pos[tot]=now;else{int t=s[i]-' a '; if (!a[now][ T]) a[now][t]=++cnt,fa[cnt]=now;now=a[now][t];}} Getfail (); F (i,2,cnt) Add_edge (fail[i],i); Tot=0;dfs (1); Memset (Head,0,sizeof (head)); Cnte=0;n=read (); F (i,1,n) {int x=read (), Y=read (); Add_edge (y,x);} Solve (1); F (i,1,n) printf ("%d\n", Ans[i]);}
bzoj2434 "NOI2011" Ali's typewriter