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的所有 ...
随机推荐
- System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.InvalidOperationException: 超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
2017/8/15 20:55:21 [AgentPayQuery_205506102_1BBBB]系统异常:System.Data.Entity.Core.EntityException: The ...
- 正则表达式中\b和\s有什么区别
字符串:abcsdsadas abc asdsadasdabcasdsa使用\sabc\s和\babc\b都能匹配中间的abc,这种方法不是重复了么,/s是匹配空格回车等得,/b网上教程说得不清楚什么 ...
- 二 js表达式与运算符
/** * Created by Administrator on 2017/12/14. * 表达式与运算符 */ //1.基本表达式 加减乘除 var a = 4; a = 7/6; var b ...
- 8.Thread的join方法
1.Thread类的join方法表示:当前线程执行结束再执行其它线程!在Thread类中有三个重载的方法分别是: public final synchronized void join(long mi ...
- HTML5特性&&canvas
1.HTML5是由W3C(万维网联盟,专注于XHTML 2.0)和WHATWG(专注于web表单和应用程序)共同合作的结果,2014年10月完成标准制定! 主要设计目的:为了在移动设备上支持多媒体. ...
- RobotFrameWork(一)robotfamework(python版)及Ride在windows安装
1.windows下的安装 (1)准备条件: python-2.7.3.msi robotframework-2.7.5.win32.exe wxPython2.8-win32-unicode-2.8 ...
- ReactiveCocoa(I)
ReactiveCocoa常见类 1. RAC中最核心的类RACSiganl: RACSiganl:信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据 解析: 信号类 ...
- 【2017-2-19】C#数据类型,数据转换,变量,常量,转义符
数据类型 一.基本数据类型 1.值类型(不可以为null) ⑴整型(可以为负数) byle,int,short,long(从小到大排列) 常用整型 int a=值(小于10位数) long b=值(1 ...
- Qt & VS2013 报错:There's no Qt version assigned to this project for platform Win32
如果你想了解关于Qt与VS2013开发环境搭建,可以至此翻页. 这里主要分享环境已搭建成功,在构建项目时遇到的报错解决方案. [1]Qt 与 VS2013开发环境构建时报错 报错界面如下: 注意:对话 ...
- hashcat 中文文档
hashcat 描述 hashcat是世界上最快,最先进的密码恢复工具. 此版本结合了以前基于CPU的hashcat(现在称为hashcat-legacy)和基于GPU的oclHashcat. H ...