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的所有 ...
随机推荐
- VS基本学习之(变量与常量)
一.变量与常量 1) 变量 由(定义+赋值+取值组成) 变量的命名规则: ① 变量名组成:字母 数字 下划线 @ 汉字 ② 首字母只能用:字母 下划线 @ 汉字(不能是数字 ...
- sql server行列转化和行列置换
行列转换: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 李四 物理 94 想变成(得到如下结果): 姓名 语文 数学 物理 ---- - ...
- Android -- GreenDao3.2的简单使用
1,最近看了一篇文章关于GreenDao的文章 ,感觉使用这个操作数据库还是很好用的,帮我们省了不少的查询代码,今天就和大家一起来简单的使用一下吧.首先这是官网地址:https://github.co ...
- 提示“此Flash Player与您的地区不相容,请重新安装Flash”的解决办法
问题原因: 因为Flash相对于HTML5,有着运算效率低.资源占用大.安全性不高等缺点,随着HTML5越来越普及,Adobe已宣布2020年正式停止支持Flash这项技术. 但Adobe公司为了利益 ...
- 《Semantic Sentence Matching with Densely-connected Recurrent and Co-attentive Information》DRCN 句子匹配
模型结构 首先是模型图: 传统的注意力机制无法保存多层原始的特征,根据DenseNet的启发,作者将循环网络的隐层的输出与最后一层连接. 另外加入注意力机制,代替原来的卷积.由于最后的特征维度过大,加 ...
- py3中reduce
前因 因为 Guido 先生讨厌 reduce.(Because Guido hates it. ) 详细过程请翻阅原文:http://www.artima.com/forums/flat.jsp?f ...
- 对SQLite 数据库的一点点了解
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它的设计目标是嵌入式的,它占用资源非常低,在嵌入式设备中,可能只需要几百k的内存就够了. SQLit ...
- Log4j基础知识
Log4J是Apache的一个开放源代码的项目.通过使用Log4J,程序员可以控制日志信息输送的目的地,包括控制台,文件,GUI组件和NT事件记录器,也可以控制每一条日志的输出格式,或通过定义每一条日 ...
- react 页面存在多 input 时
this.setState({ [e.target.name]:e.target.value }) let o = {} o[e.target.name] = e.target.value this. ...
- C#发送邮件异常:根据验证过程,远程证书无效,何解???
/// <summary> /// 发送邮件 /// </summary> /// <param name="mailSubjct">邮件主题& ...