LOJ2001 SDOI2017 树点涂色 LCT、线段树
注意到每一次\(1\ x\)操作相当于一次LCT中的access操作。由LCT复杂度证明可以知道access的总次数不会超过\(O(nlogn)\),我们只需要模拟这个access的过程并在其中动态统计每一个点的答案。
我们考虑在虚实边切换的过程中即时更新答案。设当前即将把\(y \rightarrow x\)的虚边转换为实边,设此时\(x\)的实儿子为\(p\)。那么对于\(p\)及其子树,所有点到根的路径经过的颜色数量均\(+1\);对于\(y\)及其所有点的子树,它们经过的颜色的数量均\(-1\)。那么我们只需要实现子树加减,可以使用线段树。
对于\(3\)操作也就是一个子树\(\max\)操作,同样在线段树上维护;\(2\)操作可以知道\(val_{x,y} = val_{1,x} + val_{1,y} - 2val_{1,LCA(x,y)} + 1\),所以就是线段树上的单点查询。
#include<bits/stdc++.h>
using namespace std;
int read(){
int a = 0; char c = getchar(); bool f = 0;
while(!isdigit(c)){f = c == '-'; c = getchar();}
while(isdigit(c)){
a = a * 10 + c - 48; c = getchar();
}
return f ? -a : a;
}
const int _ = 1e5 + 7;
vector < int > ch[_];
int N , M , dep[_] , dfn[_] , sz[_] , ind[_] , ts , jump[_][20];
namespace segt{
int mx[_ << 2] , mrk[_ << 2];
#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)
void init(int x , int l , int r){
if(l == r) mx[x] = dep[ind[l]];
else{init(lch , l , mid); init(rch , mid + 1 , r); mx[x] = max(mx[lch] , mx[rch]);}
}
void mark(int x , int val){mrk[x] += val; mx[x] += val;}
void down(int x){mark(lch , mrk[x]); mark(rch , mrk[x]); mrk[x] = 0;}
void modify(int x , int l , int r , int L , int R , int val){
if(l >= L && r <= R) return mark(x , val);
down(x);
if(mid >= L) modify(lch , l , mid , L , R , val);
if(mid < R) modify(rch , mid + 1 , r , L , R , val);
mx[x] = max(mx[lch] , mx[rch]);
}
int qry(int x , int l , int r , int L , int R){
if(l >= L && r <= R) return mx[x];
int mx = 0; down(x);
if(mid >= L) mx = qry(lch , l , mid , L , R);
if(mid < R) mx = max(mx , qry(rch , mid + 1 , r , L , R));
return mx;
}
#undef lch
#undef rch
}
namespace LCT{
int fa[_] , ch[_][2];
bool son(int x){return ch[fa[x]][1] == x;}
bool nroot(int x){return ch[fa[x]][1] == x || ch[fa[x]][0] == x;}
void rot(int x){
bool f = son(x); int y = fa[x] , z = fa[y] , w = ch[x][f ^ 1];
fa[x] = z; if(nroot(y)) ch[z][son(y)] = x;
fa[y] = x; ch[x][f ^ 1] = y;
ch[y][f] = w; if(w) fa[w] = y;
}
void splay(int x){while(nroot(x)){if(nroot(fa[x])) rot(son(fa[x]) == son(x) ? fa[x] : x); rot(x);}}
void access(int x){
for(int y = 0 ; x ; y = x , x = fa[x]){
splay(x);
if(ch[x][1]){
int t = ch[x][1]; while(ch[t][0]) t = ch[t][0];
segt::modify(1 , 1 , N , dfn[t] , dfn[t] + sz[t] - 1 , 1);
}
if(y){
int t = y; while(ch[t][0]) t = ch[t][0];
segt::modify(1 , 1 , N , dfn[t] , dfn[t] + sz[t] - 1 , -1);
}
ch[x][1] = y; fa[y] = x;
}
}
}
void dfs(int x , int p){
dep[x] = dep[p] + 1; ind[dfn[x] = ++ts] = x; sz[x] = 1;
jump[x][0] = p; LCT::fa[x] = p;
for(int i = 1 ; jump[x][i - 1] ; ++i) jump[x][i] = jump[jump[x][i - 1]][i - 1];
for(auto t : ch[x]) if(t != p){dfs(t , x); sz[x] += sz[t];}
}
int LCA(int x , int y){
if(dep[x] < dep[y]) swap(x , y);
for(int i = 18 ; i >= 0 ; --i)
if(dep[x] - (1 << i) >= dep[y]) x = jump[x][i];
if(x == y) return x;
for(int i = 18 ; i >= 0 ; --i)
if(jump[x][i] != jump[y][i]){x = jump[x][i]; y = jump[y][i];}
return jump[x][0];
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
N = read(); M = read();
for(int i = 1 ; i < N ; ++i){
int a = read() , b = read();
ch[a].push_back(b); ch[b].push_back(a);
}
dfs(1 , 0); segt::init(1 , 1 , N); int x , y , z;
while(M--)
switch(read()){
case 1: LCT::access(read()); break;
case 2:
x = read(); y = read(); z = LCA(x , y);
printf("%d\n" , segt::qry(1 , 1 , N , dfn[x] , dfn[x]) + segt::qry(1 , 1 , N , dfn[y] , dfn[y])
- 2 * segt::qry(1 , 1 , N , dfn[z] , dfn[z]) + 1); break;
case 3: x = read(); printf("%d\n" , segt::qry(1 , 1 , N , dfn[x] , dfn[x] + sz[x] - 1));
}
return 0;
}
LOJ2001 SDOI2017 树点涂色 LCT、线段树的更多相关文章
- [Sdoi2017]树点涂色 [lct 线段树]
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
- 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
树点涂色 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...
- bzoj4817 & loj2001 [Sdoi2017]树点涂色 LCT + 线段树
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4817 https://loj.ac/problem/2001 题解 可以发现这个题就是 bzo ...
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...
- BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...
- BZOJ4817[Sdoi2017]树点涂色——LCT+线段树
题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
同BZOJ3779. SDOI出原题,还是弱化版的. 吃枣药丸 #include <map> #include <cmath> #include <queue> # ...
- BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)
传送门 解题思路 跟重组病毒这道题很像.只是有了一个询问\(2\)的操作,然后询问\(2\)的答案其实就是\(val[x]+val[y]-2*val[lca(x,y)]+1\)(画图理解).剩下的操作 ...
随机推荐
- javascript获取手机上媒体设备,摄像头和话筒
主要运用H5的媒体接口API,MDN文档: navigator.mediaDevices(新版API),Navigator.getUserMedia(旧版API,不建议使用,但某些浏览器还支持),本文 ...
- 新款戴尔笔记本win10系统改win7 安装教程
下载U盘启动制作工具 及戴尔DELL ghost win7 旗舰版GHO 文件 下载地址:http://pan.baidu.com/s/1c17JqpU 插入制作好的U盘启动盘,开机按F2进入BIO ...
- Linux expect详解
随处可见的expect第一次见expect这个命令还是我第一次参加全量上线的时候,那是公司的一个牛人用Shell脚本写的一套自动部署.MD5 比对.发布的全量上线工具,没事的时候,看了下其中的几个脚本 ...
- zabbix 同步ldap帐号脚本
1.界面配置ldap验证(略) 2.mysql导入ldap帐号信息 #!/usr/bin/env python# -*- coding:utf-8 -*- import pymysqlimport c ...
- 【转】守护进程二三事与Supervisor
扩展阅读:理解Docker容器的进程管理 最顶层的是系统初始化时创建的root namespace(根名空间),再创建的新PID namespace就称之为child namespace(子名空间), ...
- Java多次启动相同jar程序
背景 现在很多软件都支持集群部署,但是测试环境通常资源有限,所以一般通过单台机器模拟集群部署(使用不同端口,运行相同jar包),本文的目的就是通过多种方式实现此需求. 两个程序 1.jar程序 ① s ...
- Java基础 awt Font 四种字体样式
JDK :OpenJDK-11 OS :CentOS 7.6.1810 IDE :Eclipse 2019‑03 typesetting :Markdown code ...
- spring.factories spring.schemas spring.handlers spring自动装配
org.springframework.core.io.support.SpringFactoriesLoader —— public static final String FACTORIES_RE ...
- sails 相关软件下载地址及命令
vscode1.40 https://vscode.cdn.azure.cn/stable/f359dd69833dd8800b54d458f6d37ab7c78df520/VSCodeUserS ...
- Angular8开发拼多多WebApp_汇总贴
https://coding.imooc.com/class/336.html?mc_marking=b9f5e475d0cb8922d899d416f5b4433f&mc_channel=s ...