[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\)这样它就是这条链上最深的点了。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<set>
  5. #define lc t[x].ch[0]
  6. #define rc t[x].ch[1]
  7. using namespace std;
  8. const int N=2e5+10,inf=1e9;
  9. int n,q,head[N],cnt;
  10. struct edge{int next,to;}a[N];
  11. struct Node{int ch[2],siz,lm,rm,col,fa;multiset<int> s;}t[N];
  12. multiset<int>::iterator it;
  13. void link(int x,int y) {a[++cnt]=(edge){head[x],y};head[x]=cnt;}
  14. int isroot(int x) {return t[t[x].fa].ch[0]!=x&&t[t[x].fa].ch[1]!=x;}
  15. int fin(int x) {return t[x].s.empty()?inf:*t[x].s.begin();}
  16. void pushup(int x)
  17. {
  18. t[x].siz=t[lc].siz+t[rc].siz+1;
  19. t[x].lm=min(t[lc].lm,t[lc].siz+min(t[x].col?0:inf,min(fin(x),t[rc].lm+1)));
  20. t[x].rm=min(t[rc].rm,t[rc].siz+min(t[x].col?0:inf,min(fin(x),t[lc].rm+1)));
  21. }
  22. void rotate(int x)
  23. {
  24. int y=t[x].fa,z=t[y].fa;
  25. int k=t[y].ch[1]==x;
  26. if(!isroot(y)) t[z].ch[t[z].ch[1]==y]=x; t[x].fa=z;
  27. t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].fa=y;
  28. t[x].ch[k^1]=y; t[y].fa=x;
  29. pushup(y);
  30. }
  31. void splay(int x)
  32. {
  33. while(!isroot(x))
  34. {
  35. int y=t[x].fa,z=t[y].fa;
  36. if(!isroot(y)) (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
  37. rotate(x);
  38. }
  39. pushup(x);
  40. }
  41. void Access(int x)
  42. {
  43. for(int y=0;x;y=x,x=t[x].fa)
  44. {
  45. splay(x);t[x].s.insert(t[rc].lm+1);
  46. rc=y;it=t[x].s.lower_bound(t[rc].lm+1);
  47. if(it!=t[x].s.end()&&*it==t[rc].lm+1) t[x].s.erase(it);
  48. pushup(x);
  49. }
  50. }
  51. void dfs(int x,int fr)
  52. {
  53. for(int i=head[x];i;i=a[i].next)
  54. {
  55. int R=a[i].to;if(fr==R) continue;
  56. t[R].fa=x;t[x].s.insert(inf+1);dfs(R,x);
  57. }
  58. pushup(x);
  59. }
  60. int main()
  61. {
  62. cin>>n;
  63. t[0].lm=t[0].rm=inf+1;
  64. for(int i=1,x,y;i<n;i++)
  65. scanf("%d%d",&x,&y),link(x,y),link(y,x);
  66. cin>>q;dfs(1,0);
  67. for(int i=1;i<=q;i++)
  68. {
  69. int op,x;scanf("%d%d",&op,&x);
  70. if(op==0)
  71. {
  72. Access(x);splay(x);
  73. t[x].col^=1;pushup(x);
  74. }
  75. else
  76. {
  77. Access(x);splay(x);
  78. printf("%d\n",t[x].rm>n?-1:t[x].rm);
  79. }
  80. }
  81. return 0;
  82. }

[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. [Android] 旋转照片/图片

    今天比较闲(是任务做完了,不是偷懒),就多更新几篇,补一下之前做的东西. 原文地址请保留http://www.cnblogs.com/rossoneri/p/3995306.html 推荐阅读: An ...

  2. 适用于 Windows 的自定义脚本扩展

    自定义脚本扩展在 Azure 虚拟机上下载并执行脚本. 此扩展适用于部署后配置.软件安装或其他任何配置/管理任务. 可以从 Azure 存储或 GitHub 下载脚本,或者在扩展运行时将脚本提供给 A ...

  3. 红帽7中firewall常用指令

    1.端口管理 (1)列出DMZ区域开放的端口 ~]#firewall-cmd --zone=dmz --list-ports (2)8080端口加入dmz区 ~]#firewall-cmd --zon ...

  4. MySQL索引选择不正确并详细解析OPTIMIZER_TRACE格式

    一 表结构如下: CREATE TABLE t_audit_operate_log (  Fid bigint(16) AUTO_INCREMENT,  Fcreate_time int(10) un ...

  5. orcl创建表及管理表

    常用的字段数据类型: .字符串(varchar2(n)) n表示保存最大长度,基本200作用..整数(number(n)) n位的整数,也可用int代替.小数(number(n,m)) m为小数位,n ...

  6. unbuntu 安装python包提示E: Unable to locate package python-timeout

    今天本想着在unbuntu环境下安装python的一个包,安装了几次都提示 E: Unable to locate package python-timeout 查阅了一些信息才知道,原来是一些软件源 ...

  7. 乘风破浪:LeetCode真题_033_Search in Rotated Sorted Array

    乘风破浪:LeetCode真题_033_Search in Rotated Sorted Array 一.前言     将传统的问题进行一些稍微的变形,这个时候我们可能无所适从了,因此还是实践出真知, ...

  8. Hadoop HBase概念学习系列之META表和ROOT表(六)

    在 HBase里的HRegion 里,谈过,HRegion是按照表名+开始/结束主键,即表名+主键范围来区分的.由于主键范围是连续的,所以一般用开始主键就可以表示相应的HRegion了. 不过,因为我 ...

  9. 【12】python 栈型数据结构模拟、队列型数据结构模拟

    一.压栈操作模拟 #__author:"吉*佳" #date: 2018/10/21 0021 #function:栈 # 栈:即是先进后出的一种数据结构 # (1)模拟压栈操作 ...

  10. CGJ02、BD09、西安80、北京54、CGCS2000常用坐标系详解

    一.万能地图下载器中的常用坐标系 水经注万能地图下载器中的常用的坐标系主要包括WGS84经纬度投影.WGS84 Web 墨卡托投影.WGS84 UTM 投影.北京54高斯投影.西安80高斯投影.CGC ...