询问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. 【最大流】【CODEVS】1993 草地排水

    [算法]网络流-最大流(dinic) [题解]http://www.cnblogs.com/onioncyc/p/6496532.html #include<cstdio> #includ ...

  2. 【AtCoder】ARC092 D - Two Sequences

    [题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...

  3. 【BZOJ】4766: 文艺计算姬

    [题目]给定两边节点数为n和m的完全二分图,求生成树数取模给定的p.n,m,p<=10^18. [算法]生成树计数(矩阵树定理) [题解]参考自 [bzoj4766]文艺计算姬 by WerKe ...

  4. img图片居中

    关键词:clear: both;    display: block;    margin:auto; 图片居左,居右,居中: /* Alignment */ .alignleft { display ...

  5. python学习笔记(十五)之集合

    集合:对应数学中的集合类型.集合中的元素是唯一,且无序的. 创建集合 方法一:使用{},注意python会自动删除重复元素 >>> number = {1,2,3,4,3,2,1} ...

  6. 洛谷 1.5.1 Number Triangles 数字金字塔

    Description 考虑在下面被显示的数字金字塔. 写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大. 每一步可以走到左下方的点也可以到达右下方的点. 7 3 8 8 1 0 ...

  7. LOW逼三人组(一)----冒泡算法

    排序 1.冒泡排序 冒泡算法 import random # 随机模块 def bubble_sort(li): ###################################冒泡排序#### ...

  8. CSS实现箭头效果

    有时候网页中使用箭头以增强效果,一般的做法是使用图片,今天我们使用CSSCSS来实现“箭头效果”,使用CSS我们必须兼容所有浏览器(IE6.7.8.9.10.+),Chrome,Firefox,Ope ...

  9. UVALive 5760 Alice and Bob

    题意是黑板上有n个数\(S_i\).每次操作可以把其中一个数减1或者将两个数合并为一个数.一个数变为0时,则不能再对其操作. 思路是发现最大的可操作次数为\( \sum S_i\)+(n - 1).\ ...

  10. C++——map注意事项

    1. C++标准模块库STL中提供了两种基本的关联容器:set和map.其内部实现是都是采用红黑树,但不同的是,set中结点存储的是键值,map中结点存储的是<key,value>的键值对 ...