2434: [Noi2011]阿狸的打字机 - BZOJ

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.
View Code

 

posted @ 2014-06-26 19:43  Randolph87  阅读(377)  评论(0编辑  收藏  举报