bzoj 2434: [Noi2011]阿狸的打字机
2016-04-05 07:54
411 查看
2434: [Noi2011]阿狸的打字机
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2032 Solved: 1166
[Submit][Status][Discuss]
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
aPaPBbP3
1 2
1 3
2 3
Sample Output
21
0
HINT
1<=N<=10^51<=M<=10^5
输入总长<=10^5
Source
Trie#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define N 100003 using namespace std; int n,m,len,t ,tail,sz,num,next[N*2],point ,v[N*2],c[N*2],pl ,tot=-1; char s[1000000]; int ch [30],fail ,isend ,pos ,h[N*2],fa ,dis ,a[N*2],ans ; int l ,r ,sz1; struct data { int x,y,p; };data ask ; int cmp(data a,data b) { return a.y<b.y; } void add(int x,int y) { tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; } void insert() { int now=0; for (int i=0;i<len;i++) { int x=s[i]-'a'; if (s[i]=='P') ++num,isend[now]=num,pos[num]=now,pl[i]=num; else if (s[i]=='B') now=fa[now]; else { if (!ch[now][x]) ch[now][x]=++sz; fa[ch[now][x]]=now; now=ch[now][x]; dis[i]=now; } } } void makefail() { queue<int> p; for (int i=0;i<26;i++) if (ch[0][i]) p.push(ch[0][i]),add(0,ch[0][i]); while (!p.empty()) { int now=p.front(); p.pop(); for (int i=0;i<26;i++) { if (!ch[now][i]) { ch[now][i]=ch[fail[now]][i]; continue; } int x=ch[now][i]; fail[x]=ch[fail[now]][i]; // if (ch[fail[now]][i]) add(fail[x],x); p.push(x); } } } int lowbit(int x) { return x&(-x); } void change(int x,int v) { for (int i=x;i<=sz1;i+=lowbit(i)) a[i]+=v; } int sum(int x) { int ans=0; while (x>0) { ans+=a[x]; x-=lowbit(x); } return ans; } void dfs(int now) { l[now]=++sz1; h[sz]=now; for (int i=point[now];i!=-1;i=next[i]) dfs(v[i]); r[now]=sz1; } int main() { memset(point,-1,sizeof(point)); memset(next,-1,sizeof(next)); scanf("%s",s); len=strlen(s); insert(); makefail(); dfs(0); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&ask[i].x,&ask[i].y),ask[i].p=i; sort(ask+1,ask+n+1,cmp); int j=1; int now=0; for (int i=0;i<len;i++) { int x=s[i]-'a'; if (s[i]=='P') { while (ask[j].y==pl[i]) { if (ask[j].x==ask[j].y) ans[ask[j].p]=1; else ans[ask[j].p]=sum(r[pos[ask[j].x]])-sum(l[pos[ask[j].x]]-1); j++; } } else if (s[i]=='B') change(l[now],-1),now=fa[now]; else { now=ch[now][x]; change(l[now],1); } } for (int i=1;i<=n;i++) printf("%d\n",ans[i]); }
相关文章推荐
- BaseModel
- DataBaseTool
- C语言(思维陷阱)
- Docker基本操作(一)
- [BZOJ1452][JSOI2009]Count(二维树状数组)
- 高并发图片(缩略图)处理中间层服务架构设计
- vim 编辑器常规操作
- SavaTool_归档
- [bzoj3513][MUTC2013]idiots
- 蓝桥杯省赛c++b组.1
- 我最优惠网系列(1)——HTML 解析类库HtmlAgilityPack
- 如何限制某些IP远程登陆
- 数据持久化
- eXtremeDB Performance tuning
- 组合数学--卡特兰数
- 福布斯:中国虚拟现实头盔除了便宜无其它优势
- 软件工程 《构建之法》 第四章读后感
- Debian GNU/Linux 8.4“Jessie”与7.10“Wheezy”正式发布
- 树状DP (poj 2342)
- hdu4292Food【拆点网络流】