题目描述

给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白

有两种操作:

0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑)

1 v : 询问1到v的路径上的第一个黑点,若无,输出-1

输入输出格式

输入格式:

第一行 N,Q,表示N个点和Q个操作

第二行到第N行N-1条无向边

再之后Q行,每行一个操作"0 i" 或者"1 v" (1 ≤ i, v ≤ N).

输出格式:

对每个1 v操作输出结果

输入输出样例:

9 8
1 2
1 3
2 4
2 9
5 9
7 9
8 9
6 8
1 3
0 8
1 6
1 7
0 2
1 9
0 2
1 9

输出:

-1
8
-1
2
-1

解:

题意要求我们单点修改颜色,查询距离。

这题当然不止LCT一种做法,也可以树剖。最近学了下LCT就练了一下QwQ.

我们先用一遍dfs求深度。求出深度后,LCT中维护除正常信息之外,维护点子树中黑点深度最浅的id编号以及点的col。

pushup:

inline void pushup(int x){
if(tr[x].col)tr[x].id=x;
else tr[x].id=0;
if(dep[tr[tr[x].ch[0]].id]<dep[tr[x].id])tr[x].id=tr[tr[x].ch[0]].id;
if(dep[tr[rc].id]<dep[tr[x].id])tr[x].id=tr[rc].id;
}

这个就不说了吧。

由于要dfs求深度,用前向星存边(树剖基本操作qwq),dfs即可。

(学树剖的话一定敲一下旅游那道题,基础操作比较全。)

记住,先dfs再Link!

每次单点修改,makeroot之后col^=1。

查询把v和1(伪根)split一下输出id即可。

代码:

#include<cstdio>
#define MAXN 500000
#include<iostream>
using namespace std;
#define lc tr[x].ch[0]
#define rc tr[x].ch[1]
struct node{
int ch[2],fa,rev,id,col;
}tr[500000];
int n,m,dep[MAXN],head[MAXN];
int tot,a[MAXN],b[MAXN],opt,f;
struct EDGE{
int next,to;
}e[MAXN];
inline bool root(int x){
int g=tr[x].fa;
return !(tr[g].ch[1]==x||tr[g].ch[0]==x);
}
inline void pushup(int x){
if(tr[x].col)tr[x].id=x;
else tr[x].id=0;
if(dep[tr[tr[x].ch[0]].id]<dep[tr[x].id])tr[x].id=tr[tr[x].ch[0]].id;
if(dep[tr[rc].id]<dep[tr[x].id])tr[x].id=tr[rc].id;
}inline void pushr(int x){
if(!x)return;
swap(tr[x].ch[0],tr[x].ch[1]);
tr[x].rev^=1;
}inline void pushdown(int x){
if(tr[x].rev){
pushr(tr[x].ch[0]);
pushr(tr[x].ch[1]);
tr[x].rev=0;
}
}inline void push(int x){
if(!root(x))push(tr[x].fa);
pushdown(x);
}inline void rotate(int x){
int y=tr[x].fa,z=tr[y].fa,k=tr[y].ch[1]==x;
if(!root(y))tr[z].ch[tr[z].ch[1]==y]=x;
tr[x].fa=z;tr[y].ch[k]=tr[x].ch[k^1];
if(tr[x].ch[k^1])tr[tr[x].ch[k^1]].fa=y;
tr[y].fa=x;tr[x].ch[k^1]=y;
pushup(y);pushup(x);
}inline void splay(int x){
int y,z;
push(x);
while(!root(x)){
y=tr[x].fa,z=tr[y].fa;
if(!root(y))(tr[z].ch[0]==y)^(tr[y].ch[0]==x)?rotate(x):rotate(y);
rotate(x);
}pushup(x);
}inline void access(int x){for(int y=0;x;y=x,x=tr[x].fa){splay(x);tr[x].ch[1]=y;pushup(x);}}
inline void makeroot(int x){
access(x);splay(x);pushr(x);
}inline void split(int x,int y){
makeroot(x);access(y);splay(y);
}inline void link(int x,int y){
makeroot(x);tr[x].fa=y;
}inline void add(int x,int y){
e[++tot].to=y;
e[tot].next=head[x];
head[x]=tot;
}inline void dfs(int u,int fa) {
dep[u]=dep[fa]+1;
for(register int i=head[u] ; i ; i=e[i].next) if(e[i].to!=fa) dfs(e[i].to,u);
}
int main(){
// link(1,2);link(1,3);
scanf("%d%d",&n,&m);
for(int i=1;i<n;++i){
scanf("%d%d",&a[i],&b[i]);
add(a[i],b[i]);add(b[i],a[i]);
}dep[0]=0;
dfs(1,0);
//printf("Case:1#\n");
dep[0]=2147483647;
// printf("Case:3#\n");
for(int i=1;i<n;++i)/*printf("Step%d %d %d\n",i,a[i],b[i]),*/link(a[i],b[i])/*,printf("Case:4#%d\n",i)*/;
// printf("Case:2#\n");
for(int i=1;i<=m;++i){
scanf("%d%d",&opt,&f);
if(!opt)makeroot(f),tr[f].col^=1;
else{
split(1,f);
printf("%d\n",tr[f].id==0?-1:tr[f].id);
}
}return 0;
}

地理中考:

...
int main(){
int grades=0,rp=0;
while(727){
rp++;grades++;
}
return 0;
}

题解【QTree3】的更多相关文章

  1. Qtree3题解(树链剖分(伪)+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意: 很明显吧.. 题解: 我的做法十分的暴力:树链剖分(伪)+线段树+\(set\)... ...

  2. Qtree3题解(树链剖分+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意 很易懂吧.. 题解 我的做法十分的暴力:树链剖分(伪)+线段树+ std :: set ...

  3. [题解]luogu P4116 Qtree3

    终于来到了Qtree3, 其实这是Qtree系列中最简单的一道题,并不需要线段树, 只要树链剖分的一点思想就吼了. 对于树链剖分剖出来的每一根重链,在重链上维护一个Set就好了, 每一个Set里存的都 ...

  4. QTREE系列题解

    打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ) orz神AK一星期前就虐完QTREE 避免忘记还是简单写下题解吧0 0 QTREE1 题意: 给出一颗带边权树 一个操作 ...

  5. 树链剖分&咕咕咕了好久好久的qtree3

    前言 显然qtree系列都是树链剖分辣 发现自己没有专门整理过树链剖分耶 辣么就把这篇博客魔改成树链剖分好辣(貌似除了树剖也没什么好写的) 正文 废话了辣么多终于开始了 一.树剖怎么写鸭 二.树剖有什 ...

  6. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  7. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  8. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  9. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

随机推荐

  1. elementui table fixed错位

          目前在官方没有解决这个bug前如果有人碰到类似问题.建议大家监听table数据,每次数据得到或改变的时候去重新渲染一下 /* 监听table数据对象 */ watch: { tableDa ...

  2. P4609 建筑师

    题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 n 个建筑,每个建筑的高度是 1 到 n 之间的一个整数. 小 Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同. ...

  3. 地图_SDK

    不仅仅是Google,您必须知道的全球十大地图API https://blog.csdn.net/u013068887/article/details/79322096

  4. ACwing 你能回答这些问题吗(线段树求最大连续字段和)

    给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“1 x y”,查询区间 [x,y] 中的最大连续子段和,即 maxx≤l≤r≤ymaxx≤l≤r≤y{∑ri=lA[i]∑i=l ...

  5. myeclipse操作hdfs

    myeclipse与hadoop集成我就不说了,还是简单说两句吧! 1.hadoop搭建完毕且可以正常访问(Linux搭建的集群环境 主机是windos) 2.在主机上将hadoop包解压 3.通过m ...

  6. 【NOIP2013模拟】七夕祭

    题目描述七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. TYVJ七夕祭和 ...

  7. JVM垃圾回收安全点Safe Point

    GC安全点(Safepoint) 程序执行时并非在所有地方都能停顿下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为“安全点(Safepoint) ” Safe Point的选择很重要, ...

  8. 预科班D9

    2020.09.17星期四 预科班D9 学习内容: 一.列表与字典的嵌套 大前提:将所有同学的信息存起来,取值需求 1.取第二个学生的性别 stus_info = [ {"name" ...

  9. Hashmap,Set,Map,List,ArrayList的区别

    表格: 类型 默认容量 加载因子[1] 扩容增量 底层实现 是否安全及同步方式 Vector 10 1 2倍 Object数组 安全,synchronized ArrayList 10 1 1.5倍( ...

  10. 趣图:调试bug进行时

      扩展阅读 趣图:大神写实,左脚程序继续运行,右脚程序调试 趣图:Bug 多了,总有一个会把你坑了 趣图:领导在旁,只求代码无Bug