【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'两个字母.经阿狸研究发现, ...
随机推荐
- python使用ddt模块对用例执行操作
import time import unittest import ddt from selenium import webdriver TEST_URL = "http://www.ba ...
- JAXB解析xml 的注解说明
1.将 xml 文件中的各个节点和属性信息创建对应的Java模型 2.在Java模型中的创建与 xml 文件对应的节点和属性需要用注解来表示@XmlRootElement 将一个Java类映射 ...
- 笔记本 windows 10 安装
开机按快捷键是F12,选择从usb启动.秋叶系统 很好用,推荐使用. 联想笔记本u深度一键u盘启动BIOS设置教程:准备工作:制作好u深度u盘启动盘http://rj.baidu.com/soft/d ...
- Hadoop Hive概念学习系列之hive的索引及案例(八)
hive里的索引是什么? 索引是标准的数据库技术,hive 0.7版本之后支持索引.Hive提供有限的索引功能,这不像传统的关系型数据库那样有“键(key)”的概念,用户可以在某些列上创建索引来加速某 ...
- 数据库学习:for xml path
一.开发环境 数据库:SQLServer2012 二.语法简介 for xml path它以xml形式展示查询的结果集 三.语法介绍 现在数据库中有一张表 1.基本语法 select * from B ...
- springboot与dubbo整合入门(三种方式)
Springboot与Dubbo整合三种方式详解 整合环境: jdk:8.0 dubbo:2.6.2 springboot:2.1.5 项目结构: 1.搭建项目环境: (1)创建父项目与三个子项目,创 ...
- Android 按钮常用点击事件大总结
很多学习Android程序设计的人都会发现每个人对代码的写法都有不同的偏好,比较明显的就是对控件响应事件的写法的不同.因此本文就把这些写法总结一下,比较下各种写法的优劣,希望对大家灵活地选择编码方式可 ...
- javaScript--进阶1--数据类型、操作符
一.JS基础知识背景 1.1 弱类型脚本语言 脚本语言是:弥补编译语言的不足而存在的,作为补充语言,不用编译,解析一行执行一行. 弱类型语言:简单理解定义一个变量,可以有多种数据类型.(var tem ...
- libevent reference Mannual II--library
FYI: http://www.wangafu.net/~nickm/libevent-book/TOC.html The Libevent Reference Manual: Preliminari ...
- cin的返回对象
//有时间回来补坑 //先记上几个有用的博客 https://blog.csdn.net/candj/article/details/4419585https://www.cnblogs.com/gy ...