[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. CentOS7安装mysql后无法启动服务,提示Unit not found

    首发日期: 2018-01-30 现象: 在centOS7中启动MySQL数据库提示: Failed to start mysqld.service: Unit not found [明明已经安装了, ...

  2. LeetCode题解之 Continuous Subarray Sum

    1.题目描述 2.循环计算即可 3.代码 bool checkSubarraySum(vector<int>& nums, int k) { ){ return false ; } ...

  3. WordCount系统分析与设计作业

    Gitee项目地址 https://gitee.com/gitdq/homework psp表 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划 10 10 · ...

  4. MySQL中的xtrabackup的原理解析

    xtrabackup的官方下载地址为 http://www.percona.com/software/percona-xtrabackup. xtrabackup包含两个主要的工具,即xtraback ...

  5. WebStorm 中 dva 项目用 start 命令需要不断重启项目问题

    问题: 用dva-cli 构建的项目,用webstorm进行开发,通过 npm start进行启动,经常修改了文件之后,浏览器里面的内容没有刷新,需要重新执行npm start才行. 解决办法: we ...

  6. Linux清除用户登录记录和命令历史方法(个人笔记)

    清除登陆系统成功的记录 [root@localhost root]# echo > /var/log/wtmp //此文件默认打开时乱码,可查到ip等信息 [root@localhost roo ...

  7. ansible 碎记录

    https://www.zhukun.net/archives/8167 ansible -i new/hosts new -m authorized_key -a "user=root k ...

  8. BZOJ1011:[HNOI2008]遥远的行星(乱搞)

    Description 直线上N颗行星,X=i处有行星i,行星J受到行星I的作用力,当且仅当i<=AJ.此时J受到作用力的大小为 Fi->j=Mi*Mj/(j-i) 其中A为很小的常量, ...

  9. go变量和常量

    一.变量 1. 命名规则:字母或者_下划线开头 2.“:=” 这种模式只能用于函数内部,常量const不能用这种模式来定义 二.常量 1. 常量const必须在定义的时候就赋值 2. 常量的值在整个过 ...

  10. Hadoop安装教程【转】

    原贴:http://www.powerxing.com/install-hadoop/ 当开始着手实践 Hadoop 时,安装 Hadoop 往往会成为新手的一道门槛.尽管安装其实很简单,书上有写到, ...