2434: [Noi2011]阿狸的打字机

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 2545  Solved: 1419
[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

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自动机,不行啊会爆的,因为B只能删除一个
诶,这个打字机好有意思,只能删一个的话顺着模拟下来就可以了把Trie树建出来啊,建一个AC自动机就好了【需要维护fa,别忘写了】
然后....这也是模板就是文本,和BZOJ3127挺像,用类似的想法,统计Fail树中x的子树里有多少个y的节点,就是x在y中的出现次数了
但是,怎么统计y的出现次数?想到这就不会了,看题解,好神啊
 
求Fail树的dfs序(显式建图),然后din[x]和dout[x]之间的序列就是x的子树,转换成序列问题
统计序列一段区间y用到的节点出现次数
神奇的打字机性质,发现每个y也都是模拟打字过程中的某个时间的结果,考虑离线,按y的小到大排序,依次模拟,用树状数组维护当前模拟到的字符的出现次数:
遇到新字符 add(新字符的dfs序,1)遇到B add(当前字符的dfs序,-1)
遇到P 看看是不是到了询问(注意多个询问y相同的情况),到了的话查询pos[x]的进出dfs序之间的和,就是y的出现次数了
pos[x]是第x个模板的Trie节点
查询复杂度O(nlogn)
注意:
1.你加的双向边,所以dfs判!=fa
2.中途改数组名改齐全了,别有的地方没改结果找半天
3.树状数组维护的是dfs序,大小为dfc,不是n,也不是sz(sz是从0(root=0)开始的,应该比dfc少1)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e5+5;
inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}return x*f;
}
int n,m;
char s[N];
struct ques{int x,y,i;bool operator <(const ques &r)const {return y<r.y;}
}a[N];struct edge{int v,ne;
}e[N<<1];
int cnt=0,h[N];
inline void ins(int u,int v){//printf("ins %d %d\n",u,v);cnt++;e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;cnt++;e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
int din[N],dout[N],dfc;
void dfs(int u,int fa){din[u]=++dfc;for(int i=h[u];i;i=e[i].ne) if(e[i].v!=fa) dfs(e[i].v,u);dout[u]=dfc;//printf("dfs %d %d %d\n",u,din[u],dout[u]);
}struct node{int ch[26],fa,fail;
}t[N];
int sz,pos[N],tot;
void build(char s[]){int u=0;for(int i=1;i<=n;i++){if(s[i]=='B') u=t[u].fa;else if(s[i]=='P') pos[++tot]=u;else{int c=s[i]-'a';if(!t[u].ch[c]) t[u].ch[c]=++sz;t[t[u].ch[c]].fa=u;u=t[u].ch[c];}}//for(int i=0;i<=sz;i++) printf("build %d %d %d\n",i,t[i].fa,t[i].ch[0]);
}int q[N],head,tail;
void getFail(){head=tail=1;for(int i=0;i<26;i++) if(t[0].ch[i]) q[tail++]=t[0].ch[i],ins(0,t[0].ch[i]);//!!!inswhile(head!=tail){int u=q[head++];for(int i=0;i<26;i++){int &v=t[u].ch[i];if(!v) {v=t[t[u].fail].ch[i];continue;}t[v].fail=t[t[u].fail].ch[i];q[tail++]=v;ins(t[v].fail,v);}}
}int c[N];
inline int lowbit(int x){return x&-x;}
inline void add(int p,int v){for(int i=p;i<=dfc;i+=lowbit(i))c[i]+=v;}//,printf("[add %d\n",i);}
inline int sum(int p){int re=0;for(int i=p;i;i-=lowbit(i)) re+=c[i];//,printf("sum %d %d\n",i,c[i]);return re;
}
int ans[N];
void solve(){sort(a+1,a+1+m);build(s);getFail();dfs(0,-1);int u=0,p=1,num=0;for(int i=1;i<=n;i++){//printf("hi %d %c\n",i,s[i]);if(s[i]=='B') add(din[u],-1),u=t[u].fa;else if(s[i]=='P'){num++;while(num==a[p].y){int l=din[pos[a[p].x]],r=dout[pos[a[p].x]];int t1=sum(l-1),t2=sum(r);//printf("que %d  %d %d  %d %d\n",a[p].i,l,r,t1,t2);ans[a[p].i]=t2-t1;p++;}}else{int c=s[i]-'a';u=t[u].ch[c]; //printf("hehe %d %d\n",u,din[u]);add(din[u],1);}//printf("u %d\n",u);
    }for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}
int main(){//freopen("in.txt","r",stdin);scanf("%s",s+1);m=read();n=strlen(s+1);for(int i=1;i<=m;i++) a[i].x=read(),a[i].y=read(),a[i].i=i;solve();
}

转载于:https://www.cnblogs.com/candy99/p/6220518.html

BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]相关推荐

  1. BZOJ 2434 NOI2011阿狸的打字机 AC自动机+树状数组

    如果你还没学AC自动机,请看这篇博客 Problem bzoj通道 洛谷通道 Solution 简单的说来,其实就是要快速求一个字符串在另一个字符串中出现了多少次.考虑构造AC自动机. 首先可以想到很 ...

  2. bzoj 2434 [Noi2011]阿狸的打字机(AC自动机+fail树+dfs序+树状数组)

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 3521  Solved: 1913 [Submit][S ...

  3. [bzoj 2434][Noi2011]阿狸的打字机

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory ...

  4. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

  5. BZOJ 2434 Luogu P2414 [NOI2011]阿狸的打字机 (AC自动机、树状数组)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 我写的是离线做法,不知道有没有在线做法. 转化一波题意,\(x\)在AC ...

  6. [BZOJ 2434][Noi2011]阿狸的打字机(AC自动机+树状数组+dfs序)

    Description 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: ·输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母 ...

  7. BZOJ 2434: [Noi2011]阿狸的打字机 ACAM+fail树

    title BZOJ 2434 LUOGU 2414 Description 打字机上只有 \(28\) 个按键,分别印有 \(26\) 个小写英文字母和 B.P 两个字母,是这样工作的: 输入小写字 ...

  8. bzoj 2434: [Noi2011]阿狸的打字机

    题意: 给出一个字典树,并告诉你若干串的结束位置.求第x个串在第y个串的出现次数. 题解: 不难的AC自动机+不难的主席树. 首先对于字典树建AC自动机,那么对于一个串S,假如能在这个串的结尾点不断跳 ...

  9. 【bzoj2434】[Noi2011]阿狸的打字机 AC自动机+Dfs序+树状数组

    题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...

最新文章

  1. top命令查看内容详解
  2. 台式计算机的配置清单(硬件和软件),台式电脑的配置清单和产品推荐
  3. php 取出多重数组中的一列_PHP获取数组中指定的一列实例
  4. 变频器服务器电路板维修,变频器线路板常见维修方法
  5. C#通用类库--DOS常用命令
  6. java top类,Java8 Top Tips,java8toptips
  7. Mock生成随机数据常用的类型规则
  8. jmeter压力测试(Linux与Windows)
  9. 工程制图与计算机绘图实训任务书及参考资料,水利工程制图与计算机绘图实训探讨...
  10. 查看计算机ping,通过ping命令检测主机的存活性
  11. [电机控制话题] 精辟!伺服电机、舵机、步进电机的区别
  12. Scala和Kotlin脚本编程
  13. 用STM32CubeMX生成STM32F407ZG + LAN8720A 的LWIP
  14. maven编译问题之 -The POM for XXX is invalid, transitive dependencies (if any) will not be available
  15. dashu java_Java中的大数
  16. 如何根据PPI网络进一步挖掘信息
  17. 图之邻接矩阵详解(C语言版)
  18. 企业怎样管理员工更有效?
  19. 01-初识 pygame 游戏开发
  20. 正在同步文件夹收件箱中的服务器更改,Outlook2016 收件箱同步项目数不一致问题...

热门文章

  1. oracle取_后的数字,聊聊四种Oracle数字取整函数
  2. 企业为实现网络营销更要将网络营销重点放在用户价值上
  3. 网页模板制作只为满足用户需求!
  4. 怎样才能提高搜索引擎对网站的信任度?
  5. 网站seo优化相关性需要了解哪三方面内容?
  6. 快速收录网站文章可以从这几步下手
  7. 宏基ec471g黑苹果_宏碁acer ec-471g 黑苹果配置教程
  8. android 开发清理内存_2019年 11 款最流行的安卓手机清理工具 总有一款适合你
  9. cordova flie文件目录_Cordova - 访问www目录下文件(获取www文件夹路径)
  10. 开发日记-20190511 关键词 onStart()和onResume()存在的原因(猜测篇)