[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的更多相关文章

  1. SPOJ2939 QTREE5(LCT维护子树信息)

    QWQ嘤嘤嘤 此题正规题解应该是边分治??或者是树剖(总之不是LCT) 但是我这里还是把它当成一个LCT题目来做 首先,这个题的重点还是在update上 因为有\(makeroot\)这个操作的存在, ...

  2. QTREE5 - Query on a tree V——LCT

    QTREE5 - Query on a tree V 动态点分治和动态边分治用Qtree4的做法即可. LCT: 换根后,求子树最浅的白点深度. 但是也可以不换根.类似平常换根的往上g,往下f的拼凑 ...

  3. SPOJ QTREE5 lct

    题目链接 对于每一个节点,记录这个节点所在链的信息: ls:(链的上端点)距离链内部近期的白点距离 rs:(链的下端点)距离链内部近期的白点距离 注意以上都是实边 虚边的信息用一个set维护. set ...

  4. QTREE5 - Query on a tree V(LCT)

    题意翻译 你被给定一棵n个点的树,点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的边个数. 一开始所有的点都是黑色的. 要求作以下操作: 0 i 将点i的颜 ...

  5. SPOJ QTREE5

    题意 一棵\(n\)个点的树,点从\(1\)到\(n\)编号.每个点可能有两种颜色:黑或白. 我们定义\(dist(a,b)\)为点\(a\)至点\(b\)路径上的边个数. 一开始所有的点都是黑色的. ...

  6. SPOJ - QTREE5 Query on a tree V 边分治

    题目传送门 题意:给你一棵树, 然后树上的点都有颜色,且原来为黑,现在有2个操作,1 改变某个点的颜色, 2 询问树上的白点到u点的最短距离是多少. 题解: 这里用的还是边分治的方法. 把所有东西都抠 ...

  7. SPOJ 2939 QTREE5 LCT

    维护信息的方式十分巧妙~ 维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点. 这样非常方便维护,进行区间合并,进行子树维护 很多时候在维护东西的时候最大/最小/深度最小/深度最大会相对容 ...

  8. 激!QTREE系列

    我现在才开始刷 QTREE 是不是太弱了?算了不管他…… QTREE: 树链剖分裸题(据说 lct 会超时……该说是真不愧有 spoj 的气息吗?) #include <cstdio> # ...

  9. QTREE系列题解

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

随机推荐

  1. IIS8发布Asp.net MVC程序后出现404错误,处理程序staticFile

    新部署的虚拟机,运行Asp.net MVC程序,出现如下图错误: 解决方法: 添加功能和角色->添加角色->Web服务器IIS->应用程序开发->Asp.net3.5 /Asp ...

  2. 控制台中寄宿WCF服务

    一.首先创建一个类库,用来定义WCF服务 修改服务代码定义,具体代码如下 // 注意: 使用"重构"菜单上的"重命名"命令,可以同时更改代码和配置文件中的接口名 ...

  3. 【python】python常用函数

    urlencode与urldecode 当url中包含中文或者参数包含中文,需要对中文或者特殊字符(/.&)做编码转换. urlencode的本质:把字符串转为gbk编码,再把\x替换成%.如 ...

  4. 从零自学Java-6.使用循环重复执行操作

    1.使用for循环: 2.使用while循环: 3.使用do-while循环: 4.提早退出循环(break,continue): 5.为循环命名. 程序Nines:显示1-200的整数与9的乘积 p ...

  5. Oracle EBS OPM convert dtl reservation

    --convert_dtl_reservation --created by jenrry DECLARE l_reservation_rec mtl_reservations%ROWTYPE; l_ ...

  6. SQL Server 子查询错误:No column name was specified for column 2 of 'a' error (转载)

    问: I have a MySQL query and I ran it working fine but same query showing error in SQL Server. SQL Se ...

  7. innodb_fast_shutdown的内幕

    Innodb_fast_shutdown告诉innodb在它关闭的时候该做什么工作.有三个值可以选择:1.  0表示在innodb关闭的时候,需要purge all, merge insert buf ...

  8. linux内核完全剖析——基于0.12内核-笔记(2)-统一编址和独立编址

    IO是什么 ? IO(Input and Output)是输入输出接口.是CPU和其他外部设备(如串口.LCD.触摸屏.LED等)之间通信的接口.一般的,我们说的IO就是指CPU的各种内部或外部外设. ...

  9. python基础之os.system函数

    前言 os.system方法是os模块最基础的方法,其它的方法一般在该方法基础上封装完成. os的system原理 system函数可以将字符串转化成命令在服务器上运行:其原理是每一条system函数 ...

  10. Asp.net core 2.0.1 Razor 的使用学习笔记(二)

    ASP.net core 2.0.1 中 asp.net identity 2.0.1 的基本使用(一)—启用用户管理 一.修改和启用默认的用户账户管理和角色管理 在Data目录中添加Applicat ...