询问x这个串在y中出现的次数。

fail数组有一个性质就是一旦a的fail指向b那么b所代表的字串一定是a的后缀。

所以我们看fail树(即按fail反向建树)中x的子树有多少y的结点即可。

这个操作可以使用树状数组维护dfs序操作。

By:大奕哥

 #include<bits/stdc++.h>
using namespace std;
const int N=1e5+;
int head[N],dead[N],cnt,ent,dnt,num,n,m,idx,fa[N],pos[N],l[N],r[N];
char s[N];
queue<int>q;
struct poin{
int v[],f,s;
}t[N<<];
struct node{
int to,nex;
}e[N];
struct edge{
int to,nex;
}d[N];
void add(int x,int y)
{
e[++ent].to=y;e[ent].nex=head[x];head[x]=ent;
}
void add2(int x,int y)
{
d[++dnt].to=y;d[dnt].nex=dead[x];dead[x]=dnt;
}
int tr[N<<];
inline int lowbit(int x){return x&(-x);}
int query(int x)
{
int ans=;
for(;x;x-=lowbit(x))ans+=tr[x];
return ans;
}
void update(int x,int w)
{
for(;x<=idx;x+=lowbit(x))tr[x]+=w;
}
void build()
{
int now=;
for(int i=;i<n;++i)
{
if(s[i]=='P')pos[++num]=now;
else if(s[i]=='B')now=fa[now];
else{
if(!t[now].v[s[i]-'a'])
t[now].v[s[i]-'a']=++cnt;
fa[t[now].v[s[i]-'a']]=now;
now=t[now].v[s[i]-'a'];
}
}
return;
}
void getfail()
{
for(int i=;i<;++i)
{
if(t[].v[i])
q.push(t[].v[i]),t[t[].v[i]].f=;
}
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=;i<;++i)
{
if(t[x].v[i])
{
t[t[x].v[i]].f=t[t[x].f].v[i];
q.push(t[x].v[i]);
}
else{
t[x].v[i]=t[t[x].f].v[i];
}
}
}
return;
}
void maketree()
{
for(int i=;i<=cnt;++i)
{
int x=t[i].f;int y=i;
add(x,y);
}
return;
}
void dfs(int x)
{
l[x]=++idx;
for(int i=head[x];i;i=e[i].nex)
{
int y=e[i].to;
dfs(y);
}
r[x]=++idx;
return;
}
int ans[N];
void work()
{
scanf("%d",&m);int id;int x,y;
for(int i=;i<=m;++i)
{
scanf("%d%d",&x,&y);add2(y,x);
}int now=;
for(int i=;i<n;++i)
{
if(s[i]=='B')
{
update(l[now],-);now=fa[now];
}
else if(s[i]=='P')
{
++id;
for(int j=dead[id];j;j=d[j].nex)
{
int y=pos[d[j].to];
ans[j]=query(r[y])-query(l[y]-);
}
}
else
{
now=t[now].v[s[i]-'a'];
update(l[now],);
}
}
for(int i=;i<=m;++i)
printf("%d\n",ans[i]);
return;
}
int main()
{
scanf("%s",s);
n=strlen(s);
build();
getfail();
maketree();
dfs();
work();
return ;
}

BZOJ2434 NOI2011阿狸的打字机的更多相关文章

  1. BZOJ2434 [Noi2011]阿狸的打字机 【AC自动机 + fail树 + 树状数组】

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 3610  Solved: 1960 [Submit][S ...

  2. BZOJ2434: [NOI2011]阿狸的打字机(AC自动机+dfs序+树状数组)

    [NOI2011]阿狸的打字机 题目链接:https://www.luogu.org/problemnew/show/P2414 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. ...

  3. Bzoj2434 [Noi2011]阿狸的打字机

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2536  Solved: 1415 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到 ...

  4. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

  5. BZOJ2434: [Noi2011]阿狸的打字机(AC自动机 树状数组)

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4140  Solved: 2276[Submit][Status][Discuss] Descript ...

  6. BZOJ2434[Noi2011]阿狸的打字机——AC自动机+dfs序+树状数组

    题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...

  7. BZOJ2434:[NOI2011]阿狸的打字机(AC自动机,线段树)

    Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...

  8. BZOJ2434: [Noi2011]阿狸的打字机(fail树+dfs序)

    Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...

  9. BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】

    题目分析: 画一下fail树,就会发现就是x的子树中属于y路径的,把y剖分一下,用线段树处理 $O(n*log^2 n)$. 代码: #include<bits/stdc++.h> usi ...

  10. 沉迷AC自动机无法自拔之:[BZOJ2434] [Noi2011] 阿狸的打字机

    如标题所言,我已经沉迷于AC自动机无法自拔了... 这又是一道AC自动的题,红红火火恍恍惚惚 这题目做起来真舒服 简单概括一下:\(AC\)自动机\(fail\)树上树链剖分\(+\)树状数组 这种类 ...

随机推荐

  1. 【BZOJ】1066: [SCOI2007]蜥蜴

    [算法]网络流-最大流(dinic) [题解] 构图思路: 因为石柱高度是可以被消耗的,即一根石柱可通过的蜥蜴数量有限,取舍问题中这样表示容量的属性显然可以作为网络流中的边. 于是将一根石柱拆成顶部和 ...

  2. 【NOIP】普及组2009 细胞分裂

    [算法]数论 [题解]均分的本质是A整除B,A整除B等价于A的质因数是B的子集. 1.将m1分解质因数,即m1=p1^a1*p2^a2*...*pk^ak 所以M=m1^m2=p1^(a1*m2)*p ...

  3. 【leetcode 简单】第四十一题 Excel表列序号

    给定一个Excel表格中的列名称,返回其相应的列序号. 例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ...

  4. XGBoost与LightGBM对比分析(转)

    尊重原创 来源: https://blog.csdn.net/a790209714/article/details/78086867   XGBoost的四大改进: ①改进残差函数 不用Gini作为残 ...

  5. flask插件系列之SQLAlchemy基础使用

    sqlalchemy是一个操作关系型数据库的ORM工具.下面研究一下单独使用和其在flask框架中的使用方法. 直接使用sqlalchemy操作数据库 安装sqlalchemy pip install ...

  6. for 、forEach 、 forof、 forin遍历对比

    一.遍历内容的异同 1.for 和 for...in 是针对数组下标的遍历 2.forEach 及 for...of 遍历的是数组中的元素 二.对非数字下标的处理 由于array在js中也是对象中的一 ...

  7. caffe Python API 之中值转换

    # 编写一个函数,将二进制的均值转换为python的均值 def convert_mean(binMean,npyMean): blob = caffe.proto.caffe_pb2.BlobPro ...

  8. vsts 自动部署到Azure

    如果要部署到中国区的Azure ,请先阅读 http://www.cnblogs.com/cnryb/p/7867275.html 前置条件,我把代码托管在vsts(放在GitHub上也没问题,这里不 ...

  9. linux命令:crontab命令(转)

    一.crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cro ...

  10. css绘制图标

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...