2434: [Noi2011] Ali typewriter time limit:10 Sec Memory limit:256 MB
submit:2022 solved:1158
[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^5source
Trie
Solution
A good question is worth practicing many times.
AC automata no doubt, the construction of the fail pointer at the same time, according to the fail pointer reverse build, that is, the fail tree
A subtree with the root of x follows the fail pointer backwards to find the number of points on the Y-path, indicating that X appears several times on Y.
Then, using DFS to find the timestamp of each point (i.e. the first time each node arrives and the last time it arrives), it is found that, for the subtree, it is a similar prefix and exists
Then use a line tree or a tree array to maintain
Notable points:(all for personal experience)
In the process of building the trie tree first, it should be considered that the whole operation string should be processed and separated to insert the tle
For the length of the operation string, the strlen () should not be used directly in the for loop, it should be recorded first Len=strlen () after the loop directly with Len, otherwise more tle
Do not attempt to process online, priority should be given to offline processing, otherwise there will be strange errors
For fail trees, one-way edges should be built, not two-way edges, or errors may occur
Array to open large enough, the topic of 10^5, open to 10^5+100,tyvj seconds A,codevs seconds A,bzoj Mad wa not only, Nu open 2x10^5 seconds a ... Overwhelmed
Code
#include <iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>using namespacestd;intRead () {intx=0;CharCh=GetChar (); while(ch<'0'|| Ch>'9') ch=GetChar (); while(ch>='0'&&ch<='9') {x=x*Ten+ch-'0'; ch=GetChar ();} returnx;}#defineN 210000intson[n][ -],fail[n],q[n],sz,t,len,m,ans[n],fa[n],loc[n];CharS[n],opt[n];structdata{intTo,next;} Edge[n],ask[n];intCn,cnt,head[n],heada[n],lastq[n];voidAddedge (intUintv) {CNT++;edge[cnt].to=v;edge[cnt].next=head[u];head[u]=CNT;}voidAddAsk (intXintYintz) {Ask[z].next=heada[y];heada[y]=z;ask[z].to=x;}intTree[n];inlineintLowbit (intx) {returnx& (-x);}voidChangeintLocintval) { for(intI=loc; i<=t; i+=lowbit (i)) Tree[i]+=Val;}intQueryintLoc) { intans=0; for(intI=loc; i>=1; i-=lowbit (i)) ans+=Tree[i]; returnans;}intL[n],r[n];voidDfsintx) {L[x]=++T; for(intI=HEAD[X]; I I=edge[i].next) DFS (edge[i].to); R[X]=++T; //printf ("l=%d r=%d\n", l[x],r[x]);}voidClear () {sz=1; for(intI=0; i< -; i++) son[0][i]=1;}voidBuildtrie () {intx=1, id=0; for(intI=0; i<len; i++) if(opt[i]=='P') loc[++id]=x; Else if(opt[i]=='B') x=Fa[x]; Else { if(!son[x][opt[i]-'a']) Son[x][opt[i]-'a']=++sz,fa[sz]=x; X=son[x][opt[i]-'a']; }}voidBuildfail () {intHe=0, Ta=1; q[0]=1; fail[1]=0; while(he<ta) { intnow=q[he++]; for(intI=0; i< -; i++) { if(!son[now][i])Continue; intff=Fail[now]; while(!son[ff][i]) ff=FAIL[FF]; Fail[son[now][i]]=Son[ff][i]; Q[ta++]=Son[now][i]; } } for(intI=1; i<=sz; i++) Addedge (fail[i],i);}voidWork () {intnow=1, id=0; Change (l[1],1); for(intI=0; i<len; i++) if(opt[i]=='P') {ID++; for(intJ=heada[id]; J j=ask[j].next) Ans[j]=query (R[loc[ask[j].to]])-query (l[loc[ask[j].to]]-1); } Else if(opt[i]=='B') Change (l[now],-1), now=Fa[now]; Elsenow=son[now][opt[i]-'a'],change (L[now],1);} //AcmachineintMain () {clear (); scanf ("%s", opt); len=strlen (opt); Buildtrie (); Buildfail (); M=read (); for(intX,y,i=1; i<=m; i++) x=read (), y=read (), AddAsk (x,y,i); DFS (0); Work (); for(intI=1; i<=m; i++) printf ("%d\n", Ans[i]); return 0;}
Bzoj array size by pit hard history
"BZOJ-2434" Ali typewriter ac automaton + fail tree + DFS sequence + Tree array