题解【QTree3】
题目描述
给出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】的更多相关文章
- Qtree3题解(树链剖分(伪)+线段树+set)
外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意: 很明显吧.. 题解: 我的做法十分的暴力:树链剖分(伪)+线段树+\(set\)... ...
- Qtree3题解(树链剖分+线段树+set)
外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意 很易懂吧.. 题解 我的做法十分的暴力:树链剖分(伪)+线段树+ std :: set ...
- [题解]luogu P4116 Qtree3
终于来到了Qtree3, 其实这是Qtree系列中最简单的一道题,并不需要线段树, 只要树链剖分的一点思想就吼了. 对于树链剖分剖出来的每一根重链,在重链上维护一个Set就好了, 每一个Set里存的都 ...
- QTREE系列题解
打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ) orz神AK一星期前就虐完QTREE 避免忘记还是简单写下题解吧0 0 QTREE1 题意: 给出一颗带边权树 一个操作 ...
- 树链剖分&咕咕咕了好久好久的qtree3
前言 显然qtree系列都是树链剖分辣 发现自己没有专门整理过树链剖分耶 辣么就把这篇博客魔改成树链剖分好辣(貌似除了树剖也没什么好写的) 正文 废话了辣么多终于开始了 一.树剖怎么写鸭 二.树剖有什 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
随机推荐
- oeasy教您玩转linux010103我在那pwd
我在哪pwd 回忆上次内容 我们上次列出了关于发行版详细信息文件的位置 ls /etc/*release 其中 ls是命令的名字,意味着list列表 /是整个文件系统的根root /etc是根目录下的 ...
- SpringBoot 拦截器获取http请求参数
SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 目录 SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 获取http请求参数是一种刚需 定义拦截器获取请求 为 ...
- 01_Python基础知识梳理
1.计算机知识基础 1.计算机组成 计算机底层: 点子电路,计算机只能识别两个数 0 1 硬件: 处理器(CPU), 运行内存(RAM), 主板(总线设备), 外部存储设备(硬盘U盘等 ...
- agumaster 分页方案
本文例程下载:https://files.cnblogs.com/files/xiandedanteng/agumaster20200430-1.zip 之前的分页方案有点小瑕疵,这回修正了一下. 控 ...
- Oracle中select子句取值先于order by子句执行而导致rownum伪列未按预期取值导致的问题
有这么一张表: create table hytb( id number(4,0) not null primary key, padid nvarchar2(20) not null, inputd ...
- latex pdf 转 eps
latex pdf 转 eps 方法一,使用命令行,缺点是得到的文件有点大 pdf 转 ps, pdf2ps input.pdf output.ps ps 转 eps, ps2eps input.ps ...
- 安卓自动化测试工具Monkey简单使用
一.首先安装adb 地址:http://www.downza.cn/soft/219906.html安装到D盘下,安装的过程中自己注意下不要安装上全家桶.找到这个压缩包:解压到当前文件夹: 二.将ad ...
- Linux实战(11):配置PPPOE拨号
前言: 由于需要做网站数据的抓取,普通的固定代理会容易被封禁,所以我们就用PPPOE通过动态拨号换不同的IP地址来解决该问题,下面PPPOE设置的整个方法过程: 移除NetworkManager安装r ...
- node.js conditionDebug VScode 配置
launch.json { // 使用 IntelliSense 了解相关属性. // 悬停以查看现有属性的描述. // 欲了解更多信息,请访问: https://go.microsoft.com/f ...
- (转)CrudRepository JpaRepository PagingAndSortingRepository之间的区别
1. 简介 本文介绍三种不同的Spring Data repository和它们的功能,包含以下三种: CrudRepository PagingAndSortingRepository JpaRep ...