bzoj2434: [Noi2011]阿狸的打字机

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

Source

Trie

题解:

http://blog.csdn.net/thy_asdf/article/details/47069707

code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<vector>
 7 #define lowbit(x) ((x)&(-(x)))
 8 using namespace std;
 9 char ch;
10 bool ok;
11 void read(int &x){
12     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
13     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
14     if (ok) x=-x;
15 }
16 const int maxn=100005;
17 char s[maxn];
18 int len,q,x,y,idx,pos[maxn],num[maxn],ans[maxn];
19 typedef pair<int,int> PII;
20 vector<PII> querys[maxn];
21 struct Bit{
22     int n,val[maxn];
23     void init(int x){n=x;}
24     void modify(int x,int v){for (;x<=n;x+=lowbit(x)) val[x]+=v;}
25     int query(int x){
26         int res=0;
27         for (;x;x-=lowbit(x)) res+=val[x];
28         return res;
29     }
30     int query(int l,int r){return query(r)-query(l-1);}
31 }bit;
32 struct Graph{
33     int tot,now[maxn],son[maxn],pre[maxn],idx,dfn[maxn],last[maxn];
34     void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
35     void dfs(int u){
36         dfn[u]=++idx;
37         for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) dfs(v);
38         last[u]=idx;
39     }
40     void init(){dfs(0),bit.init(idx);}
41     void change(int u,int v){bit.modify(dfn[u],v);}
42     int query(int u){return bit.query(dfn[u],last[u]);}
43 }G;
44 struct trie{
45     int tot,son[maxn][26],fai[maxn],fa[maxn];
46     int head,tail,que[maxn];
47     void build_fai(){
48         head=0,tail=1,que[1]=0,fai[0]=-1;
49         while (head<tail){
50             int u=que[++head];
51             for (int ch=0,v=son[u][ch],t;ch<26;v=son[u][++ch]) if (v){
52                 que[++tail]=v;
53                 for (t=fai[u];t>=0&&!son[t][ch];t=fai[t]);
54                 if (t>=0) fai[v]=son[t][ch]; else fai[v]=0;
55             }
56         }
57     }
58     void init(){
59         int p=0;
60         for (int i=1;i<=len;i++)
61             if (s[i]=='P') pos[p]=++idx,num[idx]=p;
62             else if (s[i]=='B') p=fa[p];
63             else{
64                 if (!son[p][s[i]-'a']) son[p][s[i]-'a']=++tot,fa[tot]=p;
65                 p=son[p][s[i]-'a'];
66             }
67         build_fai();
68         for (int i=1;i<=tot;i++) G.put(fai[i],i);
69         G.init();
70     }
71     void solve(){
72         int p=0; G.change(p,1);
73         for (int i=1;i<=len;i++)
74             if (s[i]=='P'){
75                 int y=pos[p];
76                 for (unsigned int i=0;i<querys[y].size();i++) ans[querys[y][i].second]=G.query(num[querys[y][i].first]);
77                 
78             }
79             else if (s[i]=='B') G.change(p,-1),p=fa[p];
80             else p=son[p][s[i]-'a'],G.change(p,1);
81     }
82 }T;
83 int main(){
84     scanf("%s",s+1),len=strlen(s+1);
85     read(q);
86     for (int i=1;i<=q;i++) read(x),read(y),querys[y].push_back(make_pair(x,i));
87     T.init(),T.solve();
88     for (int i=1;i<=q;i++) printf("%d
",ans[i]);
89     return 0;
90 }
原文地址:https://www.cnblogs.com/chenyushuo/p/5282032.html