题目传送门

  传送站I

  传送站II

题目大意

  阿狸有一个打字机,它有3种键:

  1. 向缓冲区追加小写字母
  2. P:打印当前缓冲区(缓冲区不变)
  3. B:删除缓冲区中最后一个字符

  然后多次询问第$x$个被打印出来的串在第$y$个被打印出来的串中出现多少次。

  每次查询相当于询问串$x$的结束节点在fail树中的子树包含多少串$y$的点。

  又因为这些串的构造比较另类。所以考虑把询问离线,然后用树状数组维护子树中关键点的个数。

Code

 /**
* bzoj
* Problem#2434
* Accepted
* Time: 620ms
* Memory: 17792k
*/
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
typedef bool boolean; const int N = 1e5 + ; typedef class IndexedTree {
public:
int s;
int ar[N]; void add(int idx, int val) {
for ( ; idx <= s; idx += (idx & (-idx)))
ar[idx] += val;
} int getSum(int idx) {
int rt = ;
for ( ; idx; idx -= (idx & (-idx)))
rt += ar[idx];
return rt;
}
}IndexedTree; typedef class TrieNode {
public:
int in, out;
TrieNode* ch[];
TrieNode* fail;
}TrieNode; TrieNode pool[N];
TrieNode *top = pool; TrieNode* newnode() {
return ++top;
} typedef class AhoCorasick {
public:
TrieNode *rt; AhoCorasick():rt(newnode()) { } void travel(char* str, TrieNode** ts) {
stack<TrieNode*> s;
TrieNode* p;
s.push(rt);
for (int i = , c, cp = ; str[i]; i++) {
if (str[i] == 'B')
s.pop();
else if (str[i] == 'P')
ts[++cp] = s.top();
else {
p = s.top(), c = str[i] - 'a';
if (!p->ch[c])
p->ch[c] = newnode();
s.push(p->ch[c]);
}
}
} void build(vector<int> *g) {
queue<TrieNode*> que;
que.push(rt);
while (!que.empty()) {
TrieNode* p = que.front();
que.pop();
for (int i = ; i < ; i++) {
TrieNode *np = p->ch[i], *f = p->fail;
if (!np) continue;
while (f && !f->ch[i]) f = f->fail;
if (!f)
np->fail = rt;
else
np->fail = f->ch[i];
que.push(np);
}
}
for (TrieNode* p = top; p != pool + ; p--)
g[p->fail - pool].push_back(p - pool);
}
}AhoCorasick; typedef class Query {
public:
int x, y, id; boolean operator < (Query b) const {
return y < b.y;
}
}Query; int m, cnt = ;
char str[N];
int *res;
Query *qs;
TrieNode** ts;
vector<int> g[N];
IndexedTree it;
AhoCorasick ac; inline void init() {
gets(str);
scanf("%d", &m);
qs = new Query[(m + )];
res = new int[(m + )];
ts = new TrieNode*[(m + )];
for (int i = ; i <= m; i++) {
scanf("%d%d", &qs[i].x, &qs[i].y);
qs[i].id = i;
}
} void dfs(int p) {
pool[p].in = ++cnt;
for (int i = ; i < (signed) g[p].size(); i++)
dfs(g[p][i]);
pool[p].out = cnt;
} inline void solve() {
ac.travel(str, ts);
ac.build(g);
it.s = (top - pool + );
dfs();
sort(qs + , qs + m + );
stack<TrieNode*> s;
s.push(ac.rt);
for (int i = , cur = , cq = ; cq <= m && str[i]; i++) {
TrieNode *p = s.top();
if (str[i] == 'B') {
it.add(p->in, -);
s.pop();
} else if (str[i] == 'P') {
cur++;
while (cq <= m && qs[cq].y == cur)
res[qs[cq].id] = it.getSum(ts[qs[cq].x]->out) - it.getSum(ts[qs[cq].x]->in - ), cq++;
} else {
p = p->ch[str[i] - 'a'];
it.add(p->in, );
s.push(p);
}
}
for (int i = ; i <= m; i++)
printf("%d\n", res[i]);
} int main() {
init();
solve();
return ;
}

bzoj 2434 阿狸的打字机 - Aho-Corasick自动机 - 树状数组的更多相关文章

  1. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

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

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

  3. BZOJ 2434 阿狸的打字机(fail树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2434 题意:阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28 ...

  4. bzoj 2434: 阿狸的打字机 fail树+离线树状数组

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 首先我们可以发现这个打字的过程本身就是在Trie上滚来滚去的过程 所以我们 ...

  5. bzoj 2434 AC自动机+树状数组

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3493  Solved: 1909[Submit][Sta ...

  6. BZOJ2434: [Noi2011]阿狸的打字机(AC自动机 树状数组)

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4140  Solved: 2276[Submit][Status][Discuss] Descript ...

  7. [NOI2011]阿狸的打字机 --- AC自动机 + 树状数组

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

  8. [BZOJ2434][Noi2011]阿狸的打字机 AC自动机+树状数组+离线

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题目中这种多个串匹配的问题,一下子就想到了AC自动机.然后发现如果要建立AC自动机, ...

  9. 【BZOJ 3529】 [Sdoi2014]数表 (莫比乌斯+分块+离线+树状数组)

    3529: [Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有 ...

随机推荐

  1. idc函数大全

    A80_addcA80_addcixA80_addciyA80_addixA80_addiyA80_cmpdA80_cmpiA80_im0A80_im1A80_im2A80_jrcA80_jrncA8 ...

  2. django项目mysql中文编码问题

    在做django+mysql项目的时候,遇到中文报错问题. 问题分析:是由于mysql数据库,字符集的问题 在cmd命令行模式进入mysql mysql -uroot -p以root身份进入mysql ...

  3. 地图服务报 error #2035

    参考:https://blog.csdn.net/iteye_20296/article/details/82395628 现在问题解决了,确实是config.xml里关于这个widget的配置url ...

  4. HDU 1757 A Simple Math Problem(矩阵)

    A Simple Math Problem [题目链接]A Simple Math Problem [题目类型]矩阵快速幂 &题解: 这是一个模板题,也算是入门了吧. 推荐一个博客:点这里 跟 ...

  5. 010-判断是否回传IsPostBack属性

    属性IsPostBack:判断是否回传 如果是第一次请求,则返回false 如果是回传请求,则返回true->说明:只有使用服务器端表单才可以正常使用IsPostBack->使用情境:当在 ...

  6. 安装Esxi 6.5

    最详细安装Esxi 6.5     Exsi 是一款虚拟化系统,与VMware,VirtualBox不同,它不需要安装在其他操作系统上,直接运行在裸机上:占用系统资源很小,易于管理,所以被大多数中小型 ...

  7. interface接口——公共规范标准

    黑马课程学习记录: 个人理解也可以看成一个类:源代码还是.java,编译后的字节文件还是.class 抽象类中可以含有普通成员方法,但是有抽象方法的必须是抽象类或者接口, 接口中只能含有抽象方法: 创 ...

  8. python自定义方法处理日志文件

    从命令行界面拷贝的内容包含过个">>>",函数的作用是用正则把每两个">>>"之间的字符取出来,然后把包含“Tracebac ...

  9. LDA模型了解及相关知识

    什么是LDA? LDA是基于贝叶斯模型的,涉及到贝叶斯模型离不开“先验分布”,“数据(似然)”和"后验分布"三块.贝叶斯相关知识:先验分布 + 数据(似然)= 后验分布. 贝叶斯模 ...

  10. Linux基础命令---修改组信息grpmod

    groupmod      修改组的基本信息,包括组名称.组ID等信息.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法 gr ...