【Bzoj 2434】[NOI 2011] 阿狸的打字机
来源:互联网 发布:windows引导修复工具 编辑:程序博客网 时间:2024/05/17 08:34
Description
阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。 打字机上只有28个按键,分别印有26个小写英文字母和'B'、'P'两个字母。经阿狸研究发现,这个打字机是这样工作的:l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后)。l 按一下印有'B'的按键,打字机凹槽中最后一个字母会消失。l 按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失。例如,阿狸输入aPaPBbP,纸上被打印的字符如下:aaaab我们把纸上打印出来的字符串从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
aPaPBbP31 21 32 3
Sample Output
210
HINT
1<=N<=10^51<=M<=10^5输入总长<=10^5
题解
经典的AC自动机+fail树+dfs序+树状数组,考试中会有点难想到用dfs序,写起来还是爽的飞起的
代码
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <queue>#include <ctime>#include <set>using namespace std;#define rep(i,l,r) for(i=l;i<=r;i++)#define ser(i,r,l) for(i=r;i>=l;i--)#define INF 100005#define inf 100000007typedef long long ll;priority_queue<int >QwQ;int l1,l=0,m,top=1,last=0,tot=1,cnt=0;int c[INF<<1],to[INF<<1],h[INF<<1],s[INF<<1],p[INF],fa[INF],t[INF][30],q[INF],fail[INF];int ans[INF],L[INF],R[INF];char s1[INF];int read(){ int k=0,f=1; char ch; while(ch<'0' || ch>'9'){ if(ch=='-')f=-1; ch=getchar(); } while(ch>='0' && ch<='9')k=(k<<1)+(k<<3)+ch-'0',ch=getchar(); return k*f;}int lowbit(int x){ return x&(-x);}void add(int x,int v){ int i,j,k; for(i=x;i<=cnt;i+=lowbit(i))c[i]+=v;}int getsum(int x){ int i,j,k=0; for(i=x;i;i-=lowbit(i))k+=c[i]; return k;}void hah(int x,int y){ to[++l]=y,h[l]=s[x],s[x]=l;}void Insert(){ int i,j,k,now=1,id=0; rep(i,0,l1-1){ if(s1[i]=='P')p[++id]=now; else if(s1[i]=='B')now=fa[now]; else { k=s1[i]-'a'+1; if(!t[now][k])t[now][k]=++tot,fa[tot]=now; now=t[now][k]; } }}void build_fail(){ int i,j,k,p; q[0]=1,fail[1]=0; while(last<top){ k=q[last++]; rep(i,1,26) if(t[k][i]){ p=fail[k]; while(!t[p][i])p=fail[p]; fail[t[k][i]]=t[p][i]; q[top++]=t[k][i]; } }}void dfs(int x){ int i,j,k; L[x]=++cnt; for(i=s[x];i;i=h[i]) dfs(to[i]); R[x]=++cnt;}void solve(){ int i,j,k,now=1,id=0; add(L[1],1); rep(i,0,l1-1){ if(s1[i]=='P'){ id++; for(j=s[id];j;j=h[j]){ k=p[to[j]]; ans[j]=getsum(R[k])-getsum(L[k]-1); } } else if(s1[i]=='B')add(L[now],-1),now=fa[now]; else now=t[now][s1[i]-'a'+1],add(L[now],1); }}void init(){ int i,j,k,x,y; tot=1; rep(i,1,26)t[0][i]=1; scanf("%s",s1); l1=strlen(s1); Insert(); build_fail(); rep(i,1,tot)hah(fail[i],i); dfs(0); l=0; memset(s,0,sizeof(s)); m=read(); rep(i,1,m){ x=read(),y=read(); hah(y,x); } solve(); rep(i,1,m)printf("%d\n",ans[i]);}void work(){ int i,j,k;}int main(){ init(); work(); return 0;}
1 0
- 【Bzoj 2434】[NOI 2011] 阿狸的打字机
- BZOJ 2434 NOI 2011 阿狸的打字机 AC自动机构造fail树
- NOI 2011 阿狸的打字机
- [省选前题目整理][BZOJ 2434][NOI 2011]阿狸的打字机(AC自动机+fail树+DFS序+树状数组)
- noi 2011 阿狸的打字机
- noi 2011 阿狸的打字机
- NOI 2011 阿狸的打字机 AC自动机
- NOI 2011 阿狸的打字机 AC自动机
- bzoj-2434: [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- BZOJ 2434 [Noi2011]阿狸的打字机
- BZOJ 2434 [Noi2011]阿狸的打字机
- bzoj 2434 [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- BZOJ 2434 [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- 【AC自动机】 BZOJ 2434 [Noi2011]阿狸的打字机
- WordPress修改功能小工具
- Codeforces Good Bye 2015 (A,B,C,D)
- 从零开始搭建Hadoop2.7.1的分布式集群
- 如何下载谷歌/百度/高德大字体地图用于打印
- 数据迁移工具-SSIS和Spoon 区别简介 -从浅入深(2.控件的基本用法)
- 【Bzoj 2434】[NOI 2011] 阿狸的打字机
- iOS应用中如何声明全局变量?
- 开发与研发
- LeetCode(26) Remove Duplicates from Sorted Array
- 手把手教你画太极图
- 从福昕阅读器转回到adobe reader
- el表达式
- python matplotlib中文显示问题
- C#中的异常语句