【BZOJ2434】阿狸的打字机(fail树,DFS序)
题意:

1<=N<=10^5

From http://blog.csdn.net/lych_cys/article/details/50646799
首先你会发现他打字的方式非常奇妙。。实际上不就是在构建一颗Tire吗?P相当于给节点标记;B相当于退回父亲节点;a..z相当于建立新的节点。
然后跑AC自动机得到fail指针。
首先得知道如何得出单个操作x,y。在后缀数组(sam,后缀树等)中,判断u是v的子串的方法是看是否是每一个后缀的前缀;而AC自动机则架构在前缀树Tire上,自然地,判断AC自动机上面的两个子串u,v(AC自动机上的子串x可以看成是从根节点到节点x连成的一个字符串),u是否是v的子串,就等价于u是否是v某个前缀的后缀!在AC自动机上,判断u是x的后缀非常简单,只要看x能否沿着fail指针走到u即可。
那么,查询u在v中出现了几次就比较明了了,只要看从根节点到v的路径中有多少个x,满足u是x的后缀即x能沿着fail指针走到u。
于是,我们可以将fail[x]作为x(这里的x不同于上面的x)的父节点建立一颗新的树,这样的话如果i是j的祖先,那么j显然可以由fail指针走到i。那么查询u,v时,将root->v的路径上的每一个点都变为1,那么答案就相当于u的子树中有多少个1了。
但是这样直接在线查询显然不行(除非写一些高大上的数据结构)。单点修改子树查询可以用dfs序+树状数组解决,因此关键是减少修改次数。我们可以离线,以v为关键字排序,这样就可以根据原来建立AC自动机的顺序进行修改了,只要在进入一个点t时+1,出去时-1,查询时自然root->v的路径上的每一个点都是1了。
var map:array[..,..]of longint;
f,fa,ind,oud,q,t,x,y,id,head,vet,next,ans,num:array[..]of longint;
n,m,i,cnt,now,tot,j,k,len,time,u,que,tmp:longint;
ch:ansistring; procedure acauto;
var t,w,u,p,i,son:longint;
begin
t:=; w:=; q[]:=;
while t<w do
begin
inc(t); u:=q[t];
for i:= to do
if map[u,i]> then
begin
son:=map[u,i];
p:=f[u];
if u= then f[son]:=
else f[son]:=map[p,i];
inc(w); q[w]:=son;
end
else
begin
p:=f[u];
if u= then map[u,i]:=
else map[u,i]:=map[p,i];
end;
end;
end; procedure add(a,b:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
head[a]:=tot;
end; procedure dfs(u:longint);
var e,v:longint;
begin
inc(time); ind[u]:=time; oud[u]:=time;
e:=head[u];
while e<> do
begin
v:=vet[e];
if ind[v]= then
begin
dfs(v);
oud[u]:=oud[v];
end;
e:=next[e];
end;
end; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; procedure qsort(l,r:longint);
var i,j,t,mid:longint;
begin
i:=l; j:=r; mid:=y[(l+r)>>];
repeat
while mid>y[i] do inc(i);
while mid<y[j] do dec(j);
if i<=j then
begin
swap(x[i],x[j]);
swap(y[i],y[j]);
swap(id[i],id[j]);
inc(i); dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; procedure ins(x,y:longint);
begin
while x<=time do
begin
t[x]:=t[x]+y;
x:=x+lowbit(x);
end;
end; function query(x:longint):longint;
begin
query:=;
while x> do
begin
query:=query+t[x];
x:=x-lowbit(x);
end;
end; begin
assign(input,'bzoj2434.in'); reset(input);
assign(output,'bzoj2434.out'); rewrite(output);
readln(ch);
m:=length(ch); len:=; cnt:=; now:=;
for i:= to m do
begin
case ch[i] of
'P':
begin
inc(n); num[n]:=now;
continue;
end;
'B':
begin
now:=fa[now];
continue;
end;
end;
u:=ord(ch[i])-ord('a')+;
if map[now,u]= then
begin
inc(cnt); map[now,u]:=cnt;
fa[cnt]:=now;
end;
now:=map[now,u];
end; acauto;
for i:= to cnt do add(f[i],i);
dfs();
readln(que);
for i:= to que do
begin
read(x[i],y[i]);
id[i]:=i;
end;
qsort(,que);
j:=; k:=; now:=;
for i:= to m do
begin
case ch[i] of
'B':
begin
ins(ind[now],-); now:=fa[now];
continue;
end;
'P':
begin
inc(j);
while (k<=que)and(y[k]=j) do
begin
tmp:=num[x[k]];
ans[id[k]]:=query(oud[tmp])-query(ind[tmp]-);
inc(k);
end;
continue;
end;
end;
now:=map[now,ord(ch[i])-ord('a')+];
ins(ind[now],);
end;
for i:= to que do writeln(ans[i]);
close(input);
close(output);
end.
【BZOJ2434】阿狸的打字机(fail树,DFS序)的更多相关文章
- [NOI2011][bzoj2434] 阿狸的打字机 [AC自动机+dfs序+fail树+树状数组]
题面 传送门 正文 最暴力的 最暴力的方法:把所有询问代表的字符串跑一遍kmp然后输出 稍微优化一下:把所有询问保存起来,把模板串相同的合并,求出next然后匹配 但是这两种方法本质没有区别,都是暴力 ...
- NOI 2011 阿狸的打字机 (AC自动机+dfs序+树状数组)
题目大意:略(太长了不好描述) 良心LOJ传送门 先对所有被打印的字符串建一颗Trie树 观察数据范围,并不能每次打印都从头到尾暴力建树,而是每遍历到一个字符就在Trie上插入这个字符,然后记录每次打 ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- 【BZOJ-2434】阿狸的打字机 AC自动机 + Fail树 + DFS序 + 树状数组
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2022 Solved: 1158[Submit][Sta ...
- BZOJ2434: [Noi2011]阿狸的打字机(fail树+dfs序)
Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...
- 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组
[BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...
- NOI2011阿狸的打字机(fail树+DFS序)
Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...
- BZOJ2434[Noi2011]阿狸的打字机——AC自动机+dfs序+树状数组
题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...
- BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )
一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...
- bzoj2434 fail树 + dfs序 + 树状数组
https://www.lydsy.com/JudgeOnline/problem.php?id=2434 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现, ...
随机推荐
- 学习http协议的三次握手和四次挥手 ~~笔记
http协议是基于tcp协议的 所以应该说是tcp协议的三次握手和四次挥手 SYN:请求建立连接,并在其序列号的字段进行序列号的初始值设定.建立连接,设置为1 FIN:用来释放一个连接.FIN=1表 ...
- Django之序列化
关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式. 1.serializers from django.core ...
- 国际化------international
1.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=& ...
- Java编程思想读书笔记_第6章(访问权限)
四种访问权限: public private 包访问权限 protected 如果没有明确指定package,则属于默认包 package access.dessert; public class C ...
- 第八届蓝桥杯省赛C/C++ A组第8题 包子凑数
参考了http://blog.csdn.net/y1196645376/article/details/69718192 思路: 数论+完全背包. 实现: #include <iostream& ...
- 读《实战GUI产品的自动化测试》:第一步——了解自动化测试,简单RFT的录制回放实例
1.了解自动化测试,什么是自动化测试?(可以参数百度百科“自动化测试”) 2.了解自动化测试 * 自动化测试如何改善产品的质量 * 自动化测试无法完全替代手工测试 * 自动化测试无法发现新的问题——适 ...
- ansible 批量推送ssh秘钥
ansible 批量推送ssh秘钥 参考:http://docs.ansible.com/ansible/authorized_key_module.html # vi /etc/ansible/ho ...
- CAD使用SetxDataLong写数据(网页版)
主要用到函数说明: MxDrawEntity::SetxDataLong 写一个long扩展数据,详细说明如下: 参数 说明 [in] BSTR val 字符串值 szAppName 扩展数据名称 n ...
- CodeFrist基础
Code First(代码先行).它思想就是先定义模型中的类,再通过这些类生成数据库.这种开发模式适合于全新的项目,它使得我们可以以代码为核心进行设计而不是先构造数据库. EF中创建数据库的表必须要有 ...
- libevent reference Mannual II--library
FYI: http://www.wangafu.net/~nickm/libevent-book/TOC.html The Libevent Reference Manual: Preliminari ...