BZOJ4545: DQS的trie
BZOJ4545: DQS的trie
https://lydsy.com/JudgeOnline/problem.php?id=4545
分析:
- 对trie用dfs建sam复杂度是\(O(n^2)\)的,因为你不能让一个复杂度带均摊的东西去一直回溯。
- 构造数据卡也很好卡,一条链边全是a,每个点连出去一条不是a的边。
- 于是我们用bfs建sam,这样复杂度是对的?
- 说这道题的做法,第一个询问每次插入时动态维护即可,第二问操作我们用lct维护后缀链接树。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 400050
#define isrt(p) (ch[f[p]][1]!=p&&ch[f[p]][0]!=p)
typedef long long ll;
int ch[N][3],fa[N],len[N],cnt=1,pos[N],n;
ll nowans;
int head[N],to[N],nxt[N],CNT,val[N];
inline void add(int u,int v,int w) {
to[++CNT]=v; nxt[CNT]=head[u]; head[u]=CNT; val[CNT]=w;
}
int tr[N];
struct LCT {
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
int ch[N][2],tag[N],f[N];
void rotate(int x) {
int y=f[x],z=f[y],k=get(x);
if(!isrt(y)) ch[z][ch[z][1]==y]=x;
ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
ch[x][!k]=y; f[y]=x; f[x]=z;
}
inline void giv(int p,int d) {
tag[p]+=d; tr[p]+=d;
}
inline void pushdown(int p) {
if(tag[p]) {
if(ls) giv(ls,tag[p]);
if(rs) giv(rs,tag[p]);
tag[p]=0;
}
}
void UPD(int p) {
if(!isrt(p)) UPD(f[p]);
pushdown(p);
}
void splay(int x) {
UPD(x);
for(int d;d=f[x],!isrt(x);rotate(x)) {
if(!isrt(d)) rotate(get(x)==get(d)?d:x);
}
}
void access(int p) {
int t=0;
while(p) {
splay(p); rs=t; t=p; p=f[p];
}
}
void cut(int p) {
access(p); splay(p); f[ls]=0; ls=0;
}
void link(int p,int q) {
f[p]=q;
}
}_;
int insert(int x,int lst) {
int p=lst,np,q,nq;
np=++cnt; lst=np;
len[np]=len[p]+1;
for(;p&&!ch[p][x];p=fa[p]) ch[p][x]=np;
if(!p) fa[np]=1,nowans+=len[np],_.link(np,1);
else {
q=ch[p][x];
if(len[q]==len[p]+1) fa[np]=q,nowans+=len[np]-(len[fa[np]]),_.link(np,q);
else {
nq=++cnt;
len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
_.UPD(q); tr[nq]=tr[q];
nowans-=(len[q]-len[fa[q]]);
fa[nq]=fa[q];
_.link(nq,fa[q]);
fa[q]=fa[np]=nq;
_.cut(q); _.link(q,nq); _.link(np,nq);
nowans+=(len[q]-len[fa[q]])+(len[nq]-len[fa[nq]])+(len[np]-len[fa[np]]);
for(;p&&ch[p][x]==q;p=fa[p]) ch[p][x]=nq;
}
}
_.access(lst), _.splay(lst), _.giv(lst,1);
return lst;
}
int Q[N];
bool vis[N];
void bfs(int x) {
int i,l=0,r=0;
Q[r++]=x; vis[x]=1;
while(l<r) {
x=Q[l++];
for(i=head[x];i;i=nxt[i]) if(!vis[to[i]]) {
vis[to[i]]=1; pos[to[i]]=insert(val[i],pos[x]); Q[r++]=to[i];
}
}
}
char w[N];
int main() {
scanf("%*d%d",&n);
int i,x,y;
pos[1]=1;
char oo[10];
for(i=1;i<n;i++) {
scanf("%d%d%s",&x,&y,oo+1);
add(x,y,oo[1]-'a'),add(y,x,oo[1]-'a');
}
bfs(1);
int m;
scanf("%d",&m);
int sz;
while(m--) {
int opt;
scanf("%d",&opt);
if(opt==1) {
printf("%lld\n",nowans);
}else if(opt==2) {
int rt;
scanf("%d%d",&rt,&sz); head[rt]=0;
for(i=1;i<sz;i++) {
scanf("%d%d%s",&x,&y,oo+1);
add(x,y,oo[1]-'a'), add(y,x,oo[1]-'a');
}
bfs(rt);
}else {
scanf("%s",w+1);
int k=strlen(w+1),p=1;
for(i=1;i<=k;i++) {
x=w[i]-'a';
if(ch[p][x]) p=ch[p][x];
else {p=ch[p][x]; break;}
}
if(!p) {puts("0");continue ;}
_.splay(p);
printf("%d\n",tr[p]);
}
}
}
BZOJ4545: DQS的trie的更多相关文章
- BZOJ4545: DQS的trie 广义后缀自动机_LCT
特别鸣神犇 fcwww 替我调出了无数个错误(没他的话我都快自闭了),祝大佬省选rp++ 板子题,给我写了一天QAQ...... 用 LCT 维护后缀树,暴力更新用 LCT 区间更新链即可 其实,在计 ...
- 【BZOJ4545】DQS的trie 后缀自动机+LCT
[BZOJ4545]DQS的trie Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符 ...
- bzoj 4545: DQS的trie
Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符.并且,它拥有极强的生长力:某个i时刻 ...
- bzoj 4545 DQS 的 Trie
老年选手不会 SAM 也不会 LCT 系列 我的数据结构好菜啊 qnq 一颗 Trie 树,$q$ 次询问,每次可以是: 1.求这棵树上本质不同的子串数量 2.插入一个子树,保证总大小不超过 $100 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- hihocoder-1014 Trie树
hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...
随机推荐
- Socket网络编程TCP、UDP演示样例
Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...
- api签名认证
参数列表: data: { sign, uid或是openId, version, timestamp, param } sign 签名一般情况下,根据如下几项生成,通过md5或是aes加密: 接口 ...
- iptables的例子1
练习1:实现主机防火墙 设置主机防火墙策略为DROP: iptables -t filter -P INPUT DROP iptables -t filter -P OUTPUT DROP i ...
- 移动端meta viewport
<meta name="viewport" content=" width=device-width, user-scalable=no, initial-scal ...
- 【python】-- web开发之jQuery
jQuery jQuery 是一个 JavaScript 函数库,jQuery库包含以下特性(HTML 元素选取.HTML 元素操作.CSS 操作.HTML 事件函数.JavaScript 特效和动画 ...
- Python日期和时间
日期和时间主要有两个库,datetime和time. datetime: 日期:datetime.date.today() 日期和时间:datetime.datetime.now() 1000天之后: ...
- 冒泡排序的三种实现(Java)
冒泡排序是非常好理解的,以从小到大排序为例,每一轮排序就找出未排序序列中最大值放在最后. 设数组的长度为N: (1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换. (2)这样 ...
- mysql复制表结构和内容
许多时候我们想复制一张表部分或者全部内容,或者只复制一张表的框架,这种需求应该说我们很常见. 其实想要实现这种需求十分简单. 表一: mysql> select * from student_i ...
- 模仿jquery框架源码 -成熟---选择器
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- Python OOP(3) staticmethod和classmethod统计实例
staticmethod 统计实例 #!python2 #-*- coding:utf-8 -*- class c1: amount_instance=0 def __init__(self): c1 ...