[SPOJ2939]Qtree5
[SPOJ2939]Qtree5
Tags:题解
题意
链接
给你\(n\)个节点的黑白树,初始全黑。每次可以翻转某点颜色,或查询距离某点最近的白点的距离。\(n\le 10^5\)。强制LCT,不准动点分。
题解
这题神了。
LCT中每个splay的中序遍历是一条直上直下的链。
维护什么呢?
\(splay\)中的\(x\)点维护\(x\)的\(splay\)子树中,在原树上深度最深和深度最浅的点、到达\(x\)的\(splay\)子树中的点在原图上的子树中、最近的白点的距离。分别记为\(lm、rm\)。
怎么维护呢?
需要维护原图信息那么开一个\(set\)维护虚子树
深度最浅的点是x的最左儿子,它的最近白点距离可能由以下几方面
- 左子树的答案
- 左子树的\(siz\)(若\(x\)为白点)
- 左子树的\(siz+1+\)右子树的答案
同理维护最深的点。
怎么查呢?
把\(x\)给\(Access\)这样它就是这条链上最深的点了。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<set>
#define lc t[x].ch[0]
#define rc t[x].ch[1]
using namespace std;
const int N=2e5+10,inf=1e9;
int n,q,head[N],cnt;
struct edge{int next,to;}a[N];
struct Node{int ch[2],siz,lm,rm,col,fa;multiset<int> s;}t[N];
multiset<int>::iterator it;
void link(int x,int y) {a[++cnt]=(edge){head[x],y};head[x]=cnt;}
int isroot(int x) {return t[t[x].fa].ch[0]!=x&&t[t[x].fa].ch[1]!=x;}
int fin(int x) {return t[x].s.empty()?inf:*t[x].s.begin();}
void pushup(int x)
{
t[x].siz=t[lc].siz+t[rc].siz+1;
t[x].lm=min(t[lc].lm,t[lc].siz+min(t[x].col?0:inf,min(fin(x),t[rc].lm+1)));
t[x].rm=min(t[rc].rm,t[rc].siz+min(t[x].col?0:inf,min(fin(x),t[lc].rm+1)));
}
void rotate(int x)
{
int y=t[x].fa,z=t[y].fa;
int k=t[y].ch[1]==x;
if(!isroot(y)) t[z].ch[t[z].ch[1]==y]=x; t[x].fa=z;
t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].fa=y;
t[x].ch[k^1]=y; t[y].fa=x;
pushup(y);
}
void splay(int x)
{
while(!isroot(x))
{
int y=t[x].fa,z=t[y].fa;
if(!isroot(y)) (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void Access(int x)
{
for(int y=0;x;y=x,x=t[x].fa)
{
splay(x);t[x].s.insert(t[rc].lm+1);
rc=y;it=t[x].s.lower_bound(t[rc].lm+1);
if(it!=t[x].s.end()&&*it==t[rc].lm+1) t[x].s.erase(it);
pushup(x);
}
}
void dfs(int x,int fr)
{
for(int i=head[x];i;i=a[i].next)
{
int R=a[i].to;if(fr==R) continue;
t[R].fa=x;t[x].s.insert(inf+1);dfs(R,x);
}
pushup(x);
}
int main()
{
cin>>n;
t[0].lm=t[0].rm=inf+1;
for(int i=1,x,y;i<n;i++)
scanf("%d%d",&x,&y),link(x,y),link(y,x);
cin>>q;dfs(1,0);
for(int i=1;i<=q;i++)
{
int op,x;scanf("%d%d",&op,&x);
if(op==0)
{
Access(x);splay(x);
t[x].col^=1;pushup(x);
}
else
{
Access(x);splay(x);
printf("%d\n",t[x].rm>n?-1:t[x].rm);
}
}
return 0;
}
[SPOJ2939]Qtree5的更多相关文章
- SPOJ2939 QTREE5(LCT维护子树信息)
QWQ嘤嘤嘤 此题正规题解应该是边分治??或者是树剖(总之不是LCT) 但是我这里还是把它当成一个LCT题目来做 首先,这个题的重点还是在update上 因为有\(makeroot\)这个操作的存在, ...
- QTREE5 - Query on a tree V——LCT
QTREE5 - Query on a tree V 动态点分治和动态边分治用Qtree4的做法即可. LCT: 换根后,求子树最浅的白点深度. 但是也可以不换根.类似平常换根的往上g,往下f的拼凑 ...
- SPOJ QTREE5 lct
题目链接 对于每一个节点,记录这个节点所在链的信息: ls:(链的上端点)距离链内部近期的白点距离 rs:(链的下端点)距离链内部近期的白点距离 注意以上都是实边 虚边的信息用一个set维护. set ...
- QTREE5 - Query on a tree V(LCT)
题意翻译 你被给定一棵n个点的树,点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的边个数. 一开始所有的点都是黑色的. 要求作以下操作: 0 i 将点i的颜 ...
- SPOJ QTREE5
题意 一棵\(n\)个点的树,点从\(1\)到\(n\)编号.每个点可能有两种颜色:黑或白. 我们定义\(dist(a,b)\)为点\(a\)至点\(b\)路径上的边个数. 一开始所有的点都是黑色的. ...
- SPOJ - QTREE5 Query on a tree V 边分治
题目传送门 题意:给你一棵树, 然后树上的点都有颜色,且原来为黑,现在有2个操作,1 改变某个点的颜色, 2 询问树上的白点到u点的最短距离是多少. 题解: 这里用的还是边分治的方法. 把所有东西都抠 ...
- SPOJ 2939 QTREE5 LCT
维护信息的方式十分巧妙~ 维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点. 这样非常方便维护,进行区间合并,进行子树维护 很多时候在维护东西的时候最大/最小/深度最小/深度最大会相对容 ...
- 激!QTREE系列
我现在才开始刷 QTREE 是不是太弱了?算了不管他…… QTREE: 树链剖分裸题(据说 lct 会超时……该说是真不愧有 spoj 的气息吗?) #include <cstdio> # ...
- QTREE系列题解
打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ) orz神AK一星期前就虐完QTREE 避免忘记还是简单写下题解吧0 0 QTREE1 题意: 给出一颗带边权树 一个操作 ...
随机推荐
- 在sublime text 3中让.vue文件的内容变成彩色
直接上步骤: 1.按住ctrl + shift + p 2.输入install Package 3.输入Vue Syntax Highlight 执行完以上3步,再次打开.vue文件,会发现里面的内容 ...
- Ubuntu 18.04 修改为静态IP
1.进入/etc/netplan目录 cd /etc/netplan 2.查看文件 ls 3.编辑 01-network-manager-all.yaml vim 01-network-manager ...
- axios的get,post方法
学习vue和nodejs的过程当中,涉及到了axios,今天为了测试,写了get和post两个方法来跟node服务端交互,结果因为header和参数弄了好久,在此记录一下,同时分享; 由于刚接触axi ...
- VScode开发Vue项目,关闭eslint代码检查,以及相关配置
Vue初始化项目时如果不小心安装了js 语法检测 功能,撸码时一个空格不对就会各种报错 个人感觉这个语法检测功能很有点过于严格,用起来十分难受,所以果断关闭eslint,找到webpack.base. ...
- 500.19 ,错误:4.00x80070005
直接把网站根目录添加上everyone权限即可
- Centos 6.5-yum安装出现错误解决方案
最近在用Centos 6.5 的时候出现了以下情况: 遇到这种问题试试以下方法: 1.检查是否能上网:ping www.baidu.com 如果显示没有连接的话,就说明没网,也就无法使用yum 命令安 ...
- python的学习之路day7-socket网络编程
python基础部分学习完了,时间也已经过了两个月左右,感觉没学到什么,可能是我学习之后忘记的太多了. 由于没钱买书,要是去培训就更没钱了,所以在网上找了一本书,感觉还不错,讲的比较好,比较详细. P ...
- 【待补充】[Python_1] Python 安装
0. 说明 安装教程网上有很多,等下次安装再补充笔记 Python 下载地址
- SmartUpload相关类的说明
㈠ File类 这个类包装了一个上传文件的所有信息.通过它,可以得到上传文件的文件名.文件大小.扩展名.文件数据等信息. File类主要提供以下方法: 1.saveAs作用:将文件换名另存. 原型: ...
- 利用单例模式设计数据库连接Model类
之前在<[php]利用php的构造函数与析构函数编写Mysql数据库查询类>(点击打开链接)写过的Mysql数据库查询类还不够完美,利用<[Java]单例模式>(点击打开链接) ...