bzoj 2434 阿狸的打字机 - Aho-Corasick自动机 - 树状数组
题目传送门
题目大意
阿狸有一个打字机,它有3种键:
- 向缓冲区追加小写字母
- P:打印当前缓冲区(缓冲区不变)
- 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自动机 - 树状数组的更多相关文章
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序
[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...
- BZOJ 2434 阿狸的打字机(fail树)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2434 题意:阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28 ...
- bzoj 2434: 阿狸的打字机 fail树+离线树状数组
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 首先我们可以发现这个打字的过程本身就是在Trie上滚来滚去的过程 所以我们 ...
- bzoj 2434 AC自动机+树状数组
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 3493 Solved: 1909[Submit][Sta ...
- BZOJ2434: [Noi2011]阿狸的打字机(AC自动机 树状数组)
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4140 Solved: 2276[Submit][Status][Discuss] Descript ...
- [NOI2011]阿狸的打字机 --- AC自动机 + 树状数组
[NOI2011] 阿狸的打字机 题目描述: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现, ...
- [BZOJ2434][Noi2011]阿狸的打字机 AC自动机+树状数组+离线
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题目中这种多个串匹配的问题,一下子就想到了AC自动机.然后发现如果要建立AC自动机, ...
- 【BZOJ 3529】 [Sdoi2014]数表 (莫比乌斯+分块+离线+树状数组)
3529: [Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有 ...
随机推荐
- css属性 background
background 在一个声明中设置所有的背景属性. background-attachment 设置背景图像是否固定或者随着页面的其余部分滚动. background-color 设置元素的背景颜 ...
- Spring中集合注入方法
集合注入重要是对数组.List.Set.map的注入,具体注入方法请参照一下代码(重点是applicationContext.xml中对这几个集合注入的方式): 1.在工程中新建一个Departmen ...
- Visual Studio快捷键查询
Ctrl+E,D —-格式化全部代码 Ctrl+E,F —-格式化选中的代码 CTRL + SHIFT + B生成解决方案 CTRL + F7 生成编译 CTRL + O 打开文件 CTRL ...
- Keras 如何利用训练好的神经网络进行预测
分成两种情况,一种是公开的训练好的模型,下载后可以使用的,一类是自己训练的模型,需要保存下来,以备今后使用. 如果是第一种情况,则参考 http://keras-cn.readthedocs.i ...
- 关于JS的几个基础题目
1.截取字符串abcdefg的efg alert("abcdefg".substring(4)); 2.判断一个字符串中出现次数最多的字符,统计这个次数 var str = 'as ...
- Saiku + Kylin 多维分析平台探索
背景 为了应对各种数据需求,通常,我们的做法是这样的: 对于临时性的数据需求:写HQL到Hive里去查一遍,然后将结果转为excel发送给需求人员. 对于周期性的.长期性的数据需求:编写脚本,结合Hi ...
- 微信小程序制作家庭记账本之三
第三天,学习别人的代码,了解到wxml跟JAVAWEB中的JSP差不太多,可以形成整个页面的轮廓.wxss对每个文本框按钮进行大小颜色修饰.json的作用很是迷惑,也不清楚各种文件是怎样相互作用的.
- node.js核心技术
一.知识结构: http模块:配置简单 的web服务,npm/cnpm工具 express框架:express中间件进行服务配置:路由:请求处理: DB服务:学习使用mysql关系型数据库: web接 ...
- Poj3253 Fence Repair (优先队列)
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 67319 Accepted: 22142 De ...
- bzoj4443 小凸玩矩阵
题目链接 二分+最大check #include<algorithm> #include<iostream> #include<cstdlib> #include& ...