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 ...
随机推荐
- IntelliJ IDEA 14.x 创建工作空间与多个Java Web项目
以往的Eclipse.NetBeans等开发工具不同,IDEA的Project相当与Eclipse的Workspace,而Module相当于Project. 下边就给出Eclipse与IDEA的概念的 ...
- 宅男福利--利用Python简单爬图
Ver beta..代码粗陋. 使用说明以Windows为例, Python版本为2.7.6 确认你电脑已经安装了Python, Windows默认安装路径为C:\Python27.如果没有安装,先下 ...
- 上传图片+浏览+裁切 Demo(无后台处理部分)
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- python 读取SQLServer数据插入到MongoDB数据库中
# -*- coding: utf-8 -*-import pyodbcimport osimport csvimport pymongofrom pymongo import ASCENDING, ...
- python 内建函数 filter,map和reduce
python 内建函数 filter,map和reduce, 三个函数比较类似,都是应用于序列的内置函数,常见的序列包括list.tuple.str等.而且三个函数都可以和lambda表达式结合使用. ...
- 遍历DOM的所有节点,输出宽度高度都大于50的元素节点名称
需要注意的问题有几点: 1.遍历所有元素节点的方式是:document.getElementsByTagName("*"),同时为了兼容性好可以再一句:document.all 2 ...
- A Neural Network in 11 lines of Python
A Neural Network in 11 lines of Python A bare bones neural network implementation to describe the in ...
- 1182-IP地址转换
描述 给定一个点分十进制的IP地址,把这个IP地址转换为二进制形式. 输入 输入只有一行,一个点分十进制的IP地址 包括四个正整数,用三个.分开,形式为a.b.c.d 其中0<=a,b,c,d& ...
- android 在Fragment里添加Theme主题
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanc ...
- 【NOIP TG 解方程】
存代码: #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> ...