Description
阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。打字机上只有28个按键,分别印有26个小写英文字母和'B'、'P'两个字母。
经阿狸研究发现,这个打字机是这样工作的:
l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后)。
l 按一下印有'B'的按键,打字机凹槽中最后一个字母会消失。
l 按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失。
例如,阿狸输入aPaPBbP,纸上被打印的字符如下:
a
aa
ab
我们把纸上打印出来的字符串从1开始顺序编号,一直到n。打字机有一个非常有趣的功能,在打字机中暗藏一个带数字的小键盘,在小键盘上输入两个数(x,y)(其中1≤x,y≤n),打字机会显示第x个打印的字符串在第y个打印的字符串中出现了多少次。
阿狸发现了这个功能以后很兴奋,他想写个程序完成同样的功能,你能帮助他么?
Input
输入的第一行包含一个字符串,按阿狸的输入顺序给出所有阿狸输入的字符。
第二行包含一个整数m,表示询问个数。
接下来m行描述所有由小键盘输入的询问。其中第i行包含两个整数x, y,表示第i个询问为(x, y)。
Output
输出m行,其中第i行包含一个整数,表示第i个询问的答案。
Sample Input
aPaPBbP
3
1 2
1 3
2 3
Sample Output
2
1
0
HINT
1<=N<=10^5
1<=M<=10^5
输入总长<=10^5
首先我们建出ac自动机,然后对于一组询问(x,y)就是从根到y字符串这条路径有多少点可以通过fail走到x节点,然后fail反向建出来的是一棵树(就叫fail树算了)
于是一组询问(x,y)就是从根到y字符串这条路径有多少点在x节点的子树中,于是我们处理出dfs序,我们就只要维护区间和就行了
对于多组询问我们就离线处理,按照他打字机的顺序遍历点,小写字母就在他的dfs序上+1,B就在现在这个节点的dfs序上-1,走到x单词的结束节点时处理询问(i,x)
1 const 2 maxn=100100; 3 type 4 node=record 5 x,y,id:longint; 6 end; 7 var 8 go:array[0..maxn,'a'..'z']of longint; 9 q:array[0..maxn]of node; 10 ch:array[0..maxn]of char; 11 e,p,fa,ll,rr,ans,fail,first,last,next,bit:array[0..maxn]of longint; 12 n,cnt,tot,now,sum:longint; 13 s:ansistring; 14 15 procedure insert(x,y:longint); 16 begin 17 inc(tot); 18 last[tot]:=y; 19 next[tot]:=first[x]; 20 first[x]:=tot; 21 end; 22 23 function nexts(x:longint;c:char):longint; 24 begin 25 if go[x,c]=0 then 26 begin 27 inc(cnt);go[x,c]:=cnt; 28 fa[cnt]:=x;ch[cnt]:=c; 29 end; 30 exit(go[x,c]); 31 end; 32 33 procedure swap(var x,y:node); 34 var 35 t:node; 36 begin 37 t:=x;x:=y;y:=t; 38 end; 39 40 procedure sort(l,r:longint); 41 var 42 i,j,y:longint; 43 begin 44 i:=l;j:=r;y:=q[(l+r)>>1].x; 45 repeat 46 while q[i].x<y do inc(i); 47 while q[j].x>y do dec(j); 48 if i<=j then 49 begin 50 swap(q[i],q[j]); 51 inc(i);dec(j); 52 end; 53 until i>j; 54 if i<r then sort(i,r); 55 if j>l then sort(l,j); 56 end; 57 58 procedure dfs(x:longint); 59 var 60 i:longint; 61 begin 62 inc(sum);ll[x]:=sum; 63 i:=first[x]; 64 while i<>0 do 65 begin 66 dfs(last[i]); 67 i:=next[i]; 68 end; 69 rr[x]:=sum; 70 end; 71 72 var 73 que:array[0..maxn]of longint; 74 l,r:longint; 75 76 procedure bfs; 77 var 78 i,j:longint; 79 c:char; 80 begin 81 que[1]:=0;l:=0;r:=0; 82 while l<=r do 83 begin 84 for c:='a' to 'z' do 85 if go[que[l],c]>0 then 86 begin 87 inc(r); 88 que[r]:=go[que[l],c]; 89 end; 90 inc(l); 91 end; 92 for i:=1 to cnt do 93 begin 94 j:=que[i];c:=ch[j];j:=fail[fa[j]]; 95 while (j<>0) and (go[j,c]=0) do 96 j:=fail[j]; 97 fail[que[i]]:=go[j,c]; 98 if fail[que[i]]=que[i] then fail[que[i]]:=0; 99 insert(fail[que[i]],que[i]); 100 end; 101 end; 102 103 function get(x:longint):longint; 104 begin 105 get:=0; 106 while x>0 do 107 begin 108 inc(get,bit[x]); 109 x:=x-(x and (-x)); 110 end; 111 end; 112 113 procedure add(x,y:longint); 114 begin 115 while x<=sum do 116 begin 117 inc(bit[x],y); 118 x:=x+(x and (-x)); 119 end; 120 end; 121 122 procedure main; 123 var 124 i,j:longint; 125 begin 126 readln(s);now:=0; 127 for i:=1 to length(s) do 128 begin 129 if s[i]='P' then 130 begin 131 inc(n); 132 e[n]:=i; 133 p[n]:=now; 134 end 135 else 136 if s[i]='B' then now:=fa[now] 137 else now:=nexts(now,s[i]); 138 end; 139 bfs; 140 dfs(0); 141 read(n); 142 for i:=1 to n do 143 read(q[i].y,q[i].x); 144 for i:=1 to n do q[i].id:=i; 145 sort(1,n); 146 j:=0;now:=0; 147 for i:=1 to n do 148 begin 149 while j<e[q[i].x] do 150 begin 151 inc(j); 152 if s[j]='B' then 153 begin 154 add(ll[now],-1); 155 now:=fa[now]; 156 end 157 else 158 if s[j]<>'P' then 159 begin 160 now:=nexts(now,s[j]); 161 add(ll[now],1); 162 end; 163 end; 164 ans[q[i].id]:=get(rr[p[q[i].y]])-get(ll[p[q[i].y]]-1); 165 end; 166 for i:=1 to n do writeln(ans[i]); 167 end; 168 169 begin 170 main; 171 end.