2434: [Noi2011]阿狸的打字机

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

Source

Trie

[Submit][Status][Discuss]

【题解】【AC自动机+树状数组】

【首先将整个大串建trie树(P、B不能算进去,遇到要特判,遇到P要将记录每个单词的数组更新;遇到B要记录当前点的父节点,以备后面删除时往回跳),再建fail树,根据fail树神奇的特性,将查询自动机上root-y的每一个结点,沿着fail指针是否会走到x的结尾点,变为查询自动机上root-y的所有结点中,有多少个在x的子树中。按照fail树跑一遍dfs序。  然后将询问离线,按y排序,每次走到一个等于y的位置就查询,用树状数组维护】

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[100010];
struct question{int num,x,y;
}ask[100010];
int nxt[100010][30],fail[100010],fa[100010],record[100010],num,sz;
int a[200010],next[200010],p[100010],tot;
int in[100010],out[100010],tp;
int tree[200010],ans[100010];
int m,len,cnt;inline int tmp(question a,question b)
{return a.y<b.y;
}
inline void add(int x,int y)
{++tot; next[tot]=p[x]; a[tot]=y; p[x]=tot;++tot; next[tot]=p[y]; a[tot]=x; p[y]=tot;
}void dfs(int now,int father)
{in[now]=++tp;int u=p[now];while (u!=0){int v=a[u];if (v!=father) dfs(v,now);u=next[u];}out[now]=tp;return;
}inline void trie()
{int now=0;for (int i=0;i<len;++i){if (s[i]>='a'&&s[i]<='z'){int x=s[i]-'a';if (!nxt[now][x]) nxt[now][x]=++sz;fa[nxt[now][x]]=now;now=nxt[now][x];}if (s[i]=='P') record[++num]=now;if (s[i]=='B') now=fa[now];}
}
inline void make_fail()
{queue<int>que;for (int i=0;i<26;++i)if (nxt[0][i]) add(0,nxt[0][i]),que.push(nxt[0][i]);while (!que.empty()){int now=que.front(); que.pop();for (int i=0;i<26;++i){int ch=nxt[now][i];if (!ch){nxt[now][i]=nxt[fail[now]][i]; continue;}int x=nxt[now][i];fail[x]=nxt[fail[now]][i];add(x,fail[x]);que.push(x);}}
}inline void init(int x,int val)
{for (int i=x;i<=tp;i+=i&(-i))tree[i]+=val;
}
inline int ask1(int x)
{int sum=0;for (int i=x;i>=1;i-=i&(-i))sum+=tree[i];return sum;
}
int main()
{int i,now,k;scanf("%s",s);len=strlen(s);trie();make_fail();dfs(0,-1);scanf("%d",&m);for (i=1;i<=m;++i)scanf("%d%d",&ask[i].x,&ask[i].y),ask[i].num=i;sort(ask+1,ask+m+1,tmp);now=0;k=1;for (i=0;i<len;++i){if (s[i]>='a'&&s[i]<='z'){int x=s[i]-'a';now=nxt[now][x];init(in[now],1);}if (s[i]=='B'){init(in[now],-1);now=fa[now];}if (s[i]=='P'){++cnt;if (cnt==ask[k].y)for (int j=k;ask[j].y==cnt;++j){int ans1=ask1(in[record[ask[j].x]]-1);int ans2=ask1(out[record[ask[j].x]]);ans[ask[j].num]=ans2-ans1;k=j+1;}}}for (i=1;i<=m;++i)printf("%d\n",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/lris-searching/p/9402977.html

【bzoj 2434】【codevs 1946】[Noi2011]阿狸的打字机(AC自动机)相关推荐

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

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

  2. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

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

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

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

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

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

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

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

  6. P2414 NOI2011阿狸的打字机 [AC自动机,dfs序]

    阿狸的打字机 题解 题目中给出的字符串就是构建TrieTrieTrie树的顺序.我们将字符串依次读入,每读入一个小写字符就相当于在TrieTrieTrie树当前节点下插入一个小写字符,读入BBB时,就 ...

  7. [luogu2414 NOI2011]阿狸的打字机 (AC自动机)

    传送门 Solution 我们知道AC自动机上如果有一点A的fail[A]->B那么B为A的一个后缀 那么我们的问题\((x,y)\)就变为在y中有多少个点直接或间接连向x的终止节点 如果写暴力 ...

  8. 【bzoj2434】阿狸的打字机 AC自动机+树状数组

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [题解] 这是一道很神的题. 先建一个AC自动机,这里需要维护一下父结点,以便删除时 ...

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

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

最新文章

  1. 【性格心理学】为什么我在关键时刻总是紧张?
  2. 《数据结构》第01章在线测试
  3. java随机抽题系统_在用java做一个在线考试系统,随机抽题遇到了问题,我写了一个随机抽题的方法,不知道在asp按钮中怎么用...
  4. dazhilu飞鸽传书 2013 官方网站
  5. java代码雨_代码雨 - java代码库 - 云代码
  6. Asp.net Request方法获取客户端的信息
  7. Qt5.9一个简单的多线程实例(类QThread)(第一种方法)
  8. DiskGenius无损调整分区大小
  9. C++11 关键字noexcept 替代 throw
  10. Map集合之HashMap
  11. php中的oop思想,OOP思想指的是什么?
  12. 使用ArcGIS软件对 .jpg 图片添加经纬网及地理配准失败的原因
  13. iter()——迭代器
  14. 2-人的发声原理和听觉原理
  15. java让一个方法等待_如何写一个“等待”的方法?
  16. Hyperopt的使用
  17. python IO模块【一】:IO类
  18. 【SLAM】VINS-MONO解析——回环检测和重定位
  19. python小项目——2048小游戏(详解)
  20. 【入门到精通】❤️「Java工程师全栈知识路线」

热门文章

  1. 简述java的线程_Java多线程的简述
  2. android 怎么获取app 字体颜色,android app 修改字体
  3. java redis 重连_突破Java面试(23-4) - Redis 复制原理
  4. 计算分数数组中去掉最低分的平均分,并打印
  5. java 对比工具_Java几款性能分析工具的对比
  6. 12306能删候补订单记录_12306候补购票功能在哪里怎么用 火车票候补购票使用攻略...
  7. 从数据库表中随机获取N条记录的SQL语句
  8. 通过nginx在window下部署项目
  9. java 监听器 分类_java过滤器和监听器详解 分类: 学习专区
  10. codeforces 110A-C语言解题报告