题解【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 ...
随机推荐
- android,在java代码中,如何给textview设置不同的颜色,以及引用color中资源设置颜色
textV.setTextColor(Color.parseColor("#FF0000")); <pre name="code" class=" ...
- 有手就行 虚拟机上安装Linux
VMware上装Linux CentOS 初学一步步来
- ZT:15 个你非了解不可的 Linux 特殊字符
https://os.51cto.com/art/202003/611595.htm 不知道大家接触 Linux 系统有多久了,可曾了解过 Linux 中有哪些特殊的字符呢?其实啊,那些特殊字符都大有 ...
- docker 停止、启动、删除镜像指令
容器 docker ps // 查看所有正在运行容器 docker stop containerId // containerId 是容器的ID docker ps -a // 查看所有容器 dock ...
- 在Linux命令行里与其他用户通信
大家好,我是良许 在 Linux 命令行里向其他用户发送信息很简单,很多命令都可以做到这点,麻烦的是你需要从众多命令中挑选一个合适的命令来使用.因此,我挑选了四种常用的 Linux 用户通信命令分享给 ...
- Ubuntu中的launcher
最近在ubuntu系统中下载了最新版的eclipse,在一个临时文件夹中解压了eclipse压缩包,然后打开eclipse,按平时常规做法,我在launcher里右键点击eclipse,选择“锁定到启 ...
- 实用js方法DataUrl转为File、url转base64
声明:仅为方便自己所需,也希望能方便他人,如有侵权,联系删除. 1,DataUrl转为File /** * DataUrl转为File * @param {String} dataUrl - data ...
- [LeetCode]1071. 字符串的最大公因子(gcd)
题目 对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 "T 能除尽 S". 返回最长字符串 X,要求满足 X 能除尽 ...
- [LeetCode]42. 接雨水(双指针,DP)
题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下, ...
- Spring源码解析 | 第二篇:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析
一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...