bzoj 3881 [Coci2015]Divljak——LCT维护parent树链并
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3881
对 S 建 SAM ,每个 T 会让 S 的 parent 树的链并答案+1;在 T 走每一步的时候,走到的节点用 LCT access 一下,就能找到该点到 parent 根的链。
给链打标记。在 access 的过程中,如果遇到已经打过这个 T 标记的点,就停止 access 。
注意实现的时候,在判断 fa[x] 有没有标记之前要先 splay(fa[x]) 。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls c[cr][0]
#define rs c[cr][1]
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
const int N=1e5+,M=2e6+,K=;
int n,ps[N],tot=,c[M][K],tc[M][K],fl[M],q[M];
int tim,dfn[M],fa[M],vl[M],tg[M],sta[M];
char s[M];
bool isrt(int x){return c[fa[x]][]!=x&&c[fa[x]][]!=x;}
void cz(int cr)
{
if(!tg[cr])return; int w=tg[cr];tg[cr]=;
vl[ls]+=w; vl[rs]+=w;
tg[ls]+=w; tg[rs]+=w;
dfn[ls]=dfn[rs]=dfn[cr];///
}
void rotate(int x)
{
int y=fa[x],z=fa[y],d=(x==c[y][]);
if(!isrt(y))c[z][y==c[z][]]=x;
fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
c[y][d]=c[x][!d]; c[x][!d]=y;
}
void splay(int x)
{
int top; sta[top=]=x;
for(int k=x;!isrt(k);k=fa[k])sta[++top]=fa[k];
for(int i=top;i;i--)cz(sta[i]);
for(int y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
if(!isrt(y))
((y==c[z][])^(x==c[y][]))?rotate(x):rotate(y);
}
void access(int x)
{
splay(x); if(dfn[x]==tim)return;
int t=;
while()
{
c[x][]=t;
if(!fa[x])
{ tg[x]++;vl[x]++;dfn[x]=tim;return;}
splay(fa[x]);//splay first
if(dfn[fa[x]]==tim)
{ tg[x]++;vl[x]++;dfn[x]=tim;return;}
t=x; x=fa[x];
}
}
void link(int x,int y){ fa[y]=x;}
int Ins()
{
int cr=,len=strlen(s+);
for(int i=;i<=len;i++)
{
int w=s[i]-'a';
if(!tc[cr][w])tc[cr][w]=++tot;
cr=tc[cr][w];
}
return cr;
}
void get_fl()
{
int he=,tl=;
for(int i=,v;i<K;i++)
if((v=tc[][i]))
{q[++tl]=v;fl[v]=;link(,v);}
else tc[][i]=;
while(he<tl)
{
int k=q[++he],pr=fl[k];
for(int i=,v;i<K;i++)
if((v=tc[k][i]))
{ q[++tl]=v;fl[v]=tc[pr][i];link(tc[pr][i],v);}
else tc[k][i]=tc[pr][i];
}
}
void solve()
{
tim++; int cr=,len=strlen(s+);
for(int i=;i<=len;i++)
{
cr=tc[cr][s[i]-'a'];
access(cr);
}
}
int main()
{
n=rdn();
for(int i=;i<=n;i++)
{ scanf("%s",s+); ps[i]=Ins();}
get_fl();
int Q=rdn(),op,x;
while(Q--)
{
op=rdn();
if(op==)
{ scanf("%s",s+); solve();}
else
{
x=rdn(); x=ps[x];
splay(x); printf("%d\n",vl[x]);
}
}
return ;
}
bzoj 3881 [Coci2015]Divljak——LCT维护parent树链并的更多相关文章
- BZOJ 3881 [COCI2015]Divljak (Trie图+Fail树+树链的并+树状数组维护dfs序)
题目大意: Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- BZOJ 3881 [Coci2015]Divljak(AC自动机+树状数组)
建立AC自动机然后,加入一个串之后考虑这个串的贡献.我们把这个串扔到AC自动机里面跑.最后对经过每一个点到的这个点在fail树的根的路径上的点有1的贡献.求链的并,我们把这些点按DFS序排序,然后把每 ...
- BZOJ 3881: [Coci2015]Divljak [AC自动机 树链的并]
3881: [Coci2015]Divljak 题意:添加新文本串,询问某个模式串在多少种文本串里出现过 模式串建AC自动机,考虑添加一个文本串,走到的节点记录下来求树链的并 方法是按dfs序排序去重 ...
- BZOJ 3881: [Coci2015]Divljak
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 553 Solved: 176[Submit][Sta ...
- bzoj 3881 [Coci2015]Divljak fail树+树链的并
题目大意 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: "1 P",Bob往自己的集合里添 ...
- BZOJ2555: SubString(后缀自动机,LCT维护Parent树)
Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支 ...
- bzoj 3881: [Coci2015]Divljak AC自动机
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3881 题解: 这道题我想出了三种做法,不过只有最后一种能过. 第一种: 首先我们把所有的 ...
- BZOJ 3881[COCI2015]Divljak (AC自动机+dfs序+lca+BIT)
显然是用AC自动机 先构建好AC自动机,当B中插入新的串时就在trie上跑,对于当前点,首先这个点所代表的串一定出现过,然后这个点指向的fail也一定出现过.那么我们把每个点fail当作父亲,建一棵f ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
随机推荐
- 10.21 crond定时任务练习
1.玩crond必须以下任务开启 [root@wen ~]# chkconfig --list crond crond 0:off 1:off 2:on ...
- redis哨兵-5
#地址: https://www.cnblogs.com/PatrickLiu/p/8444546.html #常用架构 redis1主1从+3哨兵 实现redis高可用 #redis主从 ##### ...
- GET和POST区别及缓存问题
2.就是get和post区别的缓存问题. 首先要了解什么是缓存. HTTP缓存的基本目的就是使应用执行的更快,更易扩展,但是HTTP缓存通常只适用于idempotent request(可以理解为查询 ...
- python可变参数类型 a,*args,**kwargs
a - int *args --tuple **kwargs -- dict *args是非关键字参数,用于元组,**kw是关键字参数,用于字典 可变参数 在Python函数中,还可以定义可变参数.顾 ...
- Mac版-python环境配置(二):编译器pycharm下载安装
简介 PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本 ...
- Python笔记(三)_字典与集合
字典dict 映射类型,以键-值的方式存储,通过键来取相应的值 member={'one':1,'two':2,'three':3} 创建字典member=dict('苹果'='apple','桔子' ...
- 在线常用库 + API手册
以下链接经过本人测试,均可正常访问 jQuery: http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js bootsrap: http://app ...
- fiddler如何抓取https接口
1.Fiddler工作原理: Fiddler 是以代理 web 服务器的形式工作的,它使用代理地址:127.0.0.1端口:8888. 当 Fiddler 退出的时候它会自动注销,这样就不会影响 ...
- Cocos2d之FlyBird开发---简介
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 开发FlyBird其实非常的简单,在游戏的核心部分,我们需要实现的只有: 创建一个物理世界(世界设置重力加速度) 在物理世界中添加一个动态 ...
- 浅析java设计模式(一)----异构容器,可以存储任何对象类型为其他类提供该对象
最近在着手重构一个java UI桌面项目,发现这个项目在一开始的时候由于需求不明确,以及开发人员对swing框架不熟悉等问题造成了页面代码混乱的情况:为了能够在各个类里都可以拿到其他类的引用去进行相应 ...