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 ...
随机推荐
- DIV CSS布局中position属性用法深入探究
本文向大家描述一下DIV CSS布局中的position属性的用法,position属性主要有四种属性值,任何元素的默认position的属性值均是static,静态.这节课主要讲讲relative( ...
- 修改ECSHOP,支持图片云存储化(分离到专用图片服务器)
为了提高页面加载速度和适应中国复杂的网络环境,我决定把所有商品图片都分离到专业的云存储服务器上,具有CDN加速功能. 首先,生成一个域名 img.xxxx.com 并映射到自己的云存储别名,然后把全部 ...
- jquery实现替代iframe的功能
使用iframe能很好的嵌入其他的网页或者网站,但是iframe每次加载都会浪费好多的时间,且会阻止其他元素的加载,搜索引擎也不能识别页面ifram框架中被调用的链接.文本.图片等等内容的. Html ...
- MJRefreshFooterView
实例化header和footer _header = [MJRefreshHeaderView header]; _header.scrollView = _tableView; 设置header和f ...
- .net 添加不同项目框架引用出现的问题
问题描述: winform项目添加web项目时出现问题,winform项目添加web项目类时,老是报找不到这个类的命名空间 最后才知道两个项目所建的框架不一样,一个是.net framework 4, ...
- C# const和statci readonly区别
1.const 是属于编译时的变量,它定义的常量是在对象初始化时赋值,以后不能改变他的值. 它适用于两种场景:1.取值永久不变(比如圆周率.一天包含的小时数.地球的半径等) 2.对程序性能要求非常苛 ...
- WP8教程
http://www.maiziedu.com/courses-list?technology_category=6
- (重)POJ 3020Antenna Placement
http://poj.org/problem?id=3020 呃...这个题不是很会,所以找了大神的博客做了参考,说得很详细 http://blog.csdn.net/lyy289065406/art ...
- 面向XX编程
[一篮饭特稀原创,转载请注明出自http://www.cnblogs.com/wanghafan/p/5033186.html ] 基于面向XX编程的个人理解 面向过程编程 Procedure Or ...
- c#中的delegate(委托)和event(事件)
c#中的delegate(委托)和event(事件) 一.delegate是什么东西? 完全可以把delegate理解成C中的函数指针,它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能 ...