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. chromedriver与chrome版本映射表(更新至v2.46)

    chromedriver版本 支持的Chrome版本 v2.46 v71-73 v2.45 v70-72 v2.44 v69-71 v2.43 v69-71 v2.42 v68-70 v2.41 v6 ...

  2. python的迭代器(转自廖雪峰老师python基础)

    我们已经知道,可以直接作用于for循环的数据类型有以下几种:一类是集合数据类型,如list.tuple.dict.set.str等:一类是generator,包括生成器和带yield的generato ...

  3. DirectX - External Overlay - 源代码

    Today i'm going to release a new version of my overlay.It's coded for beginners & users who want ...

  4. DCloud-MUI-JS:相关摘录

    ylbtech-DCloud-MUI-JS:相关摘录 1.返回顶部 1.JS initFun: function() { var oldBack = mui.back; mui.back = func ...

  5. Python多进程编程-进程间协作(Queue、Lock、Semaphore、Event、Pipe)

    进程与进程之间是相互独立的,互不干扰.如果多进程之间需要对同一资源操作,就需要进程间共享变量,上一篇文章介绍了进程间共享数据的三大类Value.Array.Manager,这三种类的主要区别在于管理的 ...

  6. OSX 创建 randisk(或称 tmpfs)

    创建步骤: #!/bin/bash ramdisk_size_in_mb= mount_point=/private/tmp ramdisk_size_in_sectors=$((${ramdisk_ ...

  7. python post 发送字符串

    python post 发送一段字符串 把字符串写在表单里,表单用字典格式,字符串作value import requests data={key:str} r=requests.post(url,d ...

  8. spring cloud学习--eureka 02

    开启eureka client的注解@EnableDiscoveryClient的功能类DiscoveryClient梳理图 获取server url位于类EndpointUtils的getServi ...

  9. 浅析java设计模式(一)----异构容器,可以存储任何对象类型为其他类提供该对象

    最近在着手重构一个java UI桌面项目,发现这个项目在一开始的时候由于需求不明确,以及开发人员对swing框架不熟悉等问题造成了页面代码混乱的情况:为了能够在各个类里都可以拿到其他类的引用去进行相应 ...

  10. python基础--新式类实现单例模式

    在网上看了有关python实现单例模式的博客,发现好多都是转载的,并且都是按照python2.x版本旧式类的方式写的. 虽然也能读懂,但对于我这种一开始学的就是python3.x的新手来说,心里总有点 ...