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\)(画图理解).剩下的操作 ...
随机推荐
- 记录一次JVM配置优化的案例
上周公司有一个应用,一到晚上高峰期的时候RT(响应时间)就很长.后来上服务器看了下JVM的配置,发现运维在启动参数那里把-Xss给设成了10M.导致每个线程占用的内存过大,导致内存消耗过快,其它线程排 ...
- JVM相关内容简介(转)
JAVA堆内存管理是影响性能主要因素之一.堆内存溢出是JAVA项目非常常见的故障,在解决该问题之前,必须先了解下JAVA堆内存是怎么工作的. 先看下JAVA堆内存是如何划分的,如图: JVM内存划分为 ...
- 应用Synopsys Synplify 综合的注意一个问题
在Xilinx ISE中使用Synopsys Synplify综合时,注意约束文件*.ucf需在当前工程的文件夹下.不要将其它文件夹下的同名文件的约束当成当前工程下文件的约束.
- Ubuntu 14.04 安装python3.7
下载: https://www.python.org/ftp/python/3.7.4/ .tgz文件,解压后,进入该文件夹 编译./configuremakesudo make install 当 ...
- SpringCloud:搭建基于Gateway的微服务网关(二)
0.代码 https://github.com/fengdaizang/OpenAPI 1.引入相关依赖 pom文件如下: <?xml version="1.0" encod ...
- Hash总结
算法介绍 这个没什么好说的,就是一段比较简单的代码,具体的话要看题目. 自然溢出 这个是比较好用而且容易被卡的一种Hash方式. 用\(2^{64}\)当模数然后做\(Hash\),常数比较小. 单模 ...
- dateTime格式转换
select Convert(varchar(8),GETDATE(),112) Select replace(CONVERT(varchar(8), GETDATE(), 108),':','')
- 转载:【TP5.0】TP5 Validate 验证规则
下面是部分tp5内置的验证规则: 格式验证类: 'name'=>'require' 验证某个字段的值是否为数字(采用filter_var验证),例如: number 或者 integer 'na ...
- Canal - 数据同步 - 阿里巴巴 MySQL binlog 增量订阅&消费组件
背景 早期,阿里巴巴 B2B 公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求 ,主要是基于trigger的方式获取增量变更.从 2010 年开始,公司开始逐步尝试数据库日志解析,获取增量变 ...
- 行车记录仪 MyCar Recorder (转)
行车记录仪 MyCar Recorder