bzoj 2434 [Noi2011]阿狸的打字机(fail树+离线处理+BIT)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=2434
【题意】
按照一定规则生成n个字符串,回答若干个询问:(x,y),问第x个字符串在第y个字符串中的出现次数。
【思路】
用所有的串构建AC自动机并求出fail数组,利用fail指针构建fail树,在这棵树上父亲是儿子的最大后缀。对于询问(x,y),设自动机中y对应的尾节点为pos,即统计自动机上pos-root的路径上的结点中有多少个处于fail树中的x的子树中。
一棵树的子树中的所有节点对应于dfs序上的一段连续区间,求出dfs序后,统计就可以转化为区间和问题,用到BIT。
离线处理所有的询问,统计所有关于y的询问到que[y],再用O(n)加一遍节点,我们对路上的所有节点对应+1,当访问到节点rt时,root-rt路径上的所有节点都已经访问,处理关于rt的询问即可。
总的时间复杂度为O(nlogn)。
【代码】
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int N = 1e5+;
char s[N];
int C[N],ans[N],n;
vector<pair<int,int> > que[N]; void add(int x,int v) {
while(x<N) C[x]+=v,x+=x&-x;
}
int query(int x) {
int res=;
while(x) res+=C[x],x-=x&-x;
return res;
}
struct ACauto {
int sz,ch[N][],fa[N],l[N],r[N],pos[N],f[N],dfsc;
vector<int> g[N];
ACauto() { sz=;dfsc=; memset(ch,,sizeof(ch)); }
void insert() {
int u=,id=;
for(int i=;s[i];i++) {
if(s[i]=='P') pos[++id]=u;
else if(s[i]=='B') u=fa[u];
else {
int c=s[i]-'a';
if(!ch[u][c]) {
ch[u][c]=sz; fa[sz]=u; sz++;
}
u=ch[u][c];
}
}
}
void get_Fail() {
queue<int> q;
f[]=;
for(int c=,v;c<;c++)
if(ch[][c]) f[ch[][c]]=,q.push(ch[][c]);
while(!q.empty()) {
int qr=q.front(); q.pop();
for(int c=;c<;c++) {
int u=ch[qr][c];
if(!u) continue;
q.push(u); int v=f[qr];
while(v&&!ch[v][c]) v=f[v];
f[u]=ch[v][c];
}
}
for(int i=;i<sz;i++)
g[f[i]].push_back(i);
}
void get_dfsc(int u) {
l[u]=++dfsc;
for(int i=;i<g[u].size();i++)
get_dfsc(g[u][i]);
r[u]=dfsc;
}
void solve() {
int id=,u=;
add(l[],);
for(int i=;s[i];i++) {
if(s[i]=='P') {
id++;
for(int j=;j<que[id].size();j++) {
int x=pos[que[id][j].first];
ans[que[id][j].second]=query(r[x])-query(l[x]-);
}
}
else if(s[i]=='B') add(l[u],-),u=fa[u];
else u=ch[u][s[i]-'a'],add(l[u],);
}
}
}ac; void read(int& x) {
char c=getchar(); int f=; x=;
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
x*=f;
}
int main() {
scanf("%s",s);
ac.insert();
ac.get_Fail();
ac.get_dfsc();
read(n);
int x,y;
for(int i=;i<n;i++) {
read(x),read(y);
que[y].push_back(make_pair(x,i));
}
ac.solve();
for(int i=;i<n;i++)
printf("%d\n",ans[i]);
return ;
}
bzoj 2434 [Noi2011]阿狸的打字机(fail树+离线处理+BIT)的更多相关文章
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )
一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...
- bzoj 2434 [Noi2011]阿狸的打字机 AC自动机
[Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4001 Solved: 2198[Submit][Status][D ...
- BZOJ 2434: [Noi2011]阿狸的打字机 AC自动机+fail树+线段树
Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...
- 【BZOJ 2434】 [Noi2011]阿狸的打字机 fail树+树状数组
就是考了一个fail树的神奇应用我们建出fail树之后,发现我们就是在求y到根的路径上所有的点在以x为根的子树里的个数,这个我们离线后用树状数组+dfs序即可解决 #include <cstdi ...
- BZOJ 2434 [Noi2011]阿狸的打字机(AC自动机)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [题目大意] 给出一个打印的过程,'a'-'z'表示输入字母,P表示打印该字符串 ...
- bzoj 2434 [Noi2011]阿狸的打字机——AC自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2434 dfs AC自动机,走过的点权值+1,回溯的时候权值-1:走到询问的 y 串的节点,看 ...
- bzoj 2434: 阿狸的打字机 fail树+离线树状数组
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 首先我们可以发现这个打字的过程本身就是在Trie上滚来滚去的过程 所以我们 ...
- bzoj 2434: [Noi2011]阿狸的打字机
#include<cstdio> #include<iostream> #include<cstring> #define M 100008 using names ...
随机推荐
- j2ee中如何拦截jsp页面?
加filter: public class RightFilter implements Filter { public void init(FilterConfig filterConfig) th ...
- python偏函数(functool.partail)
functool.partail 方法可以为一个函数生成偏函数 import functools def f(a,b,c,d): print a,b,c,d a='a' b='b' f1=functo ...
- 基于C#的SolidWorks插件开发(1)--SolidWorks API接口介绍
这是两年前毕业时写的一篇关于SolidWorks插件开发与公司PDM集成的毕业设计,最近闲来无事拿出来整理一下,大神们可以略过. 1.1 SolidWorks API接口 正确调用SolidWor ...
- C#中的lock关键字(初识)
http://kb.cnblogs.com/page/88513/ 首先给出MSDN的定义: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互 ...
- CAShapeLayer--备用
之前讲过CALayer动画相关知识,再来看看更加复杂的CAShapeLayer相关的动画知识. 普通CALayer在被初始化时是需要给一个frame值的,这个frame值一般都与给定view的boun ...
- hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)
http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others) ...
- Python编程规范及性能优化(转载)
转载地址:http://codeweblog.com/python编程规范及性能优化/
- MongoDB 配置文件启动
MongoDB 服务启动有两种方式:一种是直接命令启动,一种是通过配置文件启动 1.命令启动: mongod -dbpath C:\data\db -logpath C:\data\log\mongo ...
- 深度观察:腾讯收购大众点评背景下的O2O大格局
[亿欧导读] 腾讯入股大众点评获得20%股权,详情解读:①大众点评:独立自主为底线,要钱大于要流量:②腾讯:承认原生活服务O2O失败,丰富移动支付应用场景:③美团承受压力,拉手窝窝继续苦等买家:④BA ...
- 网上测试了很多关于PYTHON的WEBSOCKET样例,下面这个才成功了
这是最底层的, 嘿嘿,我 还是习惯搞个框架来实现急需要的功能... 这个东东玩得很有意思的.. 服务器端的代码: import simplejson import socket import sys ...