bzoj 4545

给定一个踹树,支持几种操作。

  • 本质不同子串询问
  • 加入子树
  • 询问字符串\(S\) 在树上的出现次数。

好码好码

重点就是维护\(parent\) 树,考虑用\(LCT\)维护此树。

第三问就是匹配点的\(right\)集合大小,算一算就可以了。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200010; int read () {
int q=0,f=1;char ch=getchar();
while(!isdigit(ch)) {
if(ch=='-')f=-1;ch=getchar();
}
while(isdigit(ch)){
q=q*10+ch-'0';ch=getchar();
}
return q*f;
}
long long ans;
int opt,x,y,n,q;
struct LCT {
int son[MAXN][2];
int fa[MAXN];
int v[MAXN];
int tag[MAXN];
int rev[MAXN];
int getson(int x) {
return son[fa[x]][1] == x;
}
int isroot(int x) {
return son[fa[x]][0] != x and son[fa[x]][1] != x;
}
void down(int now) {
swap(son[now][0],son[now][1]);
rev[now] ^= 1;
}
void Add_val(int x,int k) {
if(x) {
v[x] += k;
tag[x] += k;
}
}
void pushdown(int now) {
if(rev[now]) {
down(son[now][0]);
down(son[now][1]);
rev[now] = 0;
}
if(tag[now]) {
Add_val(son[now][0],tag[now]);
Add_val(son[now][1],tag[now]);
tag[now] = 0;
}
}
void dfs(int now) {
if(!isroot(now)) {
dfs(fa[now]);
}
pushdown(now);
}
void rotate(int now) {
int y = fa[now];
int z = fa[y];
int wht = getson(now);
fa[now] = z;
if(!isroot(y)) {
son[z][y == son[z][1]] = now;
}
fa[son[now][wht ^ 1]] = y;
son[y][wht] = son[now][wht ^ 1];
fa[y] = now;
son[now][wht ^ 1] = y;
}
void splay(int now) {
dfs(now);
for(int i = fa[now]; !isroot(now) ; rotate(now),i = fa[now]) {
if(!isroot(i)) {
rotate(getson(now) == getson(i) ? i : now);
}
}
}
void access(int now) {
for(int i = 0;now;i = now,now = fa[now]) {
splay(now);
son[now][1] = i;
}
}
void makeroot(int now) {
access(now);
splay(now);
down(now);
}
void link(int x,int y) {
makeroot(x);
fa[x] = y;
}
void cut(int x,int y) {
makeroot(x);
access(y);
splay(y);
son[y][0] = fa[x] = 0;
}
void Add(int x,int y,int k) {
makeroot(x);
access(y);
splay(y);
Add_val(y,k);
}
int query(int now) {
splay(now);
return v[now];
}
}lct; struct SAM {
int ch[MAXN][3];
int len[MAXN];
int fail[MAXN];
int Cnt;
SAM() {
Cnt = 1;
}
int Copy(int c) {
int now = ++Cnt;
for(int i = 0;i <= 2; ++i) {
ch[now][i] = ch[c][i];
}
return now;
}
void link(int x,int y) {
fail[x] = y;
lct.link(x,y);
ans += len[x] - len[y];
}
int work(int p,int c) {
int q = ch[p][c];
int nq = Copy(q);
len[nq] = len[p] + 1;
lct.v[nq] = lct.query(q);
lct.cut(q,fail[q]);
ans -= len[q] - len[fail[q]];
link(nq,fail[q]);
link(q,nq);
for( ; ch[p][c] == q ; p = fail[p]) {
ch[p][c] = nq;
}
return nq;
}
int insert(int p,int c) {
int cur;
if(ch[p][c]) {
cur = len[ch[p][c]] == len[p] + 1 ? ch[p][c] : work(p,c);
}
else {
cur = ++Cnt;
len[cur] = len[p] + 1;
for( ; p and !ch[p][c] ; p = fail[p]) {
ch[p][c] = cur;
}
if(!p) {
link(cur,1);
}
else if(len[ch[p][c]] == len[p] + 1) {
link(cur,ch[p][c]);
}
else {
link(cur,work(p,c));
}
}
lct.Add(cur,1,1);
return cur;
}
}sam; struct graph {
int head[MAXN];
int cnt;
graph () {
cnt = 0;
}
int ver[MAXN];
int nxt[MAXN];
int val[MAXN];
int vis[MAXN];
int pos[MAXN];
void add(int u,int v,int w) {
ver[++cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt;
val[cnt] = w;
}
void Add(int u,int v,int w) {
add(u,v,w);
add(v,u,w);
}
void dfs(int now) {
vis[now] = 1;
for(int i = head[now];i;i=nxt[i]) {
int y = ver[i];
if(vis[y]) {
continue;
}
pos[y] = sam.insert(pos[now],val[i]);
dfs(y);
}
}
}G;
char s[MAXN]; int main () {
x = read(),n = read();
for(int i = 1;i < n; ++i) {
x = read(),y = read();
scanf("%s",s);
G.Add(x,y,s[0] - 'a');
}
G.pos[1] = 1;
G.dfs(1);
q = read();
while(q--) {
opt = read();
if(opt == 1) {
cout<<ans<<endl;
}
else if(opt == 2) {
x = read(),y = read();
for(int i = 1;i < y; ++i) {
int X = read(),Y = read();
scanf("%s",s);
G.Add(X,Y,s[0] - 'a');
}
G.dfs(x);
}
else {
scanf("%s",s);int len = strlen(s);
int p = 1;
int tag = 1;
for(int i = 0;i < len; ++i) {
if(!sam.ch[p][s[i] - 'a']) {
cout<<0<<endl;
tag = 0;
break;
}
p = sam.ch[p][s[i] - 'a'];
}
if(tag) {
cout<<lct.query(p)<<endl;
}
}
}
return 0;
}

BZOJ 4545的更多相关文章

  1. bzoj 4545: DQS的trie

    Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符.并且,它拥有极强的生长力:某个i时刻 ...

  2. bzoj 4545 DQS 的 Trie

    老年选手不会 SAM 也不会 LCT 系列 我的数据结构好菜啊 qnq 一颗 Trie 树,$q$ 次询问,每次可以是: 1.求这棵树上本质不同的子串数量 2.插入一个子树,保证总大小不超过 $100 ...

  3. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  4. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  5. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  6. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  7. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  8. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  9. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

随机推荐

  1. vue工程本地代码请求http发生跨域提示错误解决方法

    这个可以使用代理进行跨域,这样看来跨域的方法就有几种了,对于iframe中的用postmassage,对于vue工程中的跨域则使用代理模式. 代理模式配置如下: 在config文件夹下找到index. ...

  2. 从Java future 到 Guava ListenableFuture实现异步调用

    从Java future 到 Guava ListenableFuture实现异步调用 置顶 2016年04月24日 09:11:14 皮斯特劳沃 阅读数:17570 标签: java异步调用线程非阻 ...

  3. Python 进阶_闭包 & 装饰器

    目录 目录 闭包 函数的实质和属性 闭包有什么好处 小结 装饰器 更加深入的看看装饰器的执行过程 带参数的装饰器 装饰器的叠加 小结 装饰器能解决什么问题 小结 闭包 Closure: 如果内层函数引 ...

  4. Linux系统CPU占用率较高问题排查思路

    作为 Linux 运维工程师,在日常工作中我们会遇到 Linux服务器上出现CPU负载达到100%居高不下的情况,如果CPU 持续跑高,则会影响业务系统的正常运行,带来企业损失. 很多运维的同学遇到这 ...

  5. fpm rpm制作

    使用fpm命令制作rpm包并安装 工作中有如下情况需要将文件打包rpm: 避免重复工作,将源码程序打包为rpm 使用yum发布项目,项目打包为rpm 将自己写好的程序打包为rpm,提供给用户下载 其他 ...

  6. [USACO 07NOV]电话线Telephone Wire

    题目描述 Farmer John's cows are getting restless about their poor telephone service; they want FJ to rep ...

  7. RSA加密、解密实现原理

    RSA加密.解密实现原理 1.公钥.私钥

  8. python小学堂-基础调用

    tem='xiaoq {0}iang'print(tem.capitalize())#首字母大学print(tem.center(30)) #居中显示iprint(tem.endswith(" ...

  9. HDU 1577 WisKey的眼神

    WisKey的眼神 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  10. 56.Decode String(解码字符串)

    Level:   Medium 题目描述: Given an encoded string, return it's decoded string. The encoding rule is: k[e ...