维护信息的方式十分巧妙~

维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点.

这样非常方便维护,进行区间合并,进行子树维护

很多时候在维护东西的时候最大/最小/深度最小/深度最大会相对容易维护,所以如果用树剖/LCT维护信息时发现很难维护的话可以采用这种套路.

因为动态树是可以维护子树信息的,也可以 ​,所以如果维护深度最深的信息的话只需 ​ 就可以做到.

code:

  1. #include <bits/stdc++.h>
  2. #define N 100006
  3. #define inf 1000000
  4. #define setIO(s) freopen(s".in","r",stdin)
  5. using namespace std;
  6. int n,edges;
  7. int hd[N],to[N<<1],nex[N<<1],col[N];
  8. void add(int u,int v)
  9. {
  10. nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
  11. }
  12. struct Link_Cut_Tree
  13. {
  14. #define lson p[x].ch[0]
  15. #define rson p[x].ch[1]
  16. struct Node
  17. {
  18. int ch[2],f,size,lmn,rmn;
  19. multiset<int>s;
  20. int get() { return s.empty()?inf:*s.begin(); }
  21. }p[N];
  22. int get(int x) { return p[p[x].f].ch[1]==x; }
  23. int isrt(int x) { return !(p[p[x].f].ch[0]==x||p[p[x].f].ch[1]==x); }
  24. void pushup(int x)
  25. {
  26. p[x].size=p[lson].size+p[rson].size+1;
  27. p[x].lmn=min(p[lson].lmn, p[lson].size+min(col[x]?0:inf, min(p[x].get(), p[rson].lmn+1)));
  28. p[x].rmn=min(p[rson].rmn, p[rson].size+min(col[x]?0:inf, min(p[x].get(), p[lson].rmn+1)));
  29. }
  30. void rotate(int x)
  31. {
  32. int old=p[x].f,fold=p[old].f,which=get(x);
  33. if(!isrt(old)) p[fold].ch[p[fold].ch[1]==old]=x;
  34. p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old;
  35. p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold;
  36. pushup(old),pushup(x);
  37. }
  38. void splay(int x)
  39. {
  40. int u=x,v=0,fa;
  41. for(;!isrt(u);u=p[u].f);
  42. for(u=p[u].f;(fa=p[x].f)!=u;rotate(x))
  43. if(p[fa].f!=u)
  44. rotate(get(fa)==get(x)?fa:x);
  45. }
  46. void Access(int x)
  47. {
  48. for(int y=0;x;y=x,x=p[x].f)
  49. {
  50. splay(x);
  51. if(rson)
  52. {
  53. p[x].s.insert(p[rson].lmn+1);
  54. }
  55. if(y)
  56. {
  57. p[x].s.erase(p[x].s.find(p[y].lmn+1));
  58. }
  59. rson=y;
  60. pushup(x);
  61. }
  62. }
  63. #undef lson
  64. #undef rson
  65. }lct;
  66. void dfs(int u,int ff)
  67. {
  68. lct.p[u].f=ff;
  69. for(int i=hd[u];i;i=nex[i])
  70. {
  71. int v=to[i];
  72. if(v==ff) continue;
  73. dfs(v,u);
  74. lct.p[u].s.insert(inf+1);
  75. }
  76. lct.pushup(u);
  77. }
  78. int main()
  79. {
  80. // setIO("input");
  81. int i,j;
  82. scanf("%d",&n);
  83. for(i=1;i<n;++i)
  84. {
  85. int u,v;
  86. scanf("%d%d",&u,&v);
  87. add(u,v);
  88. add(v,u);
  89. }
  90. lct.p[0].lmn=lct.p[0].rmn=inf;
  91. dfs(1,0);
  92. int m;
  93. scanf("%d",&m);
  94. for(i=1;i<=m;++i)
  95. {
  96. int op,u;
  97. scanf("%d%d",&op,&u);
  98. if(op==0)
  99. {
  100. lct.Access(u);
  101. lct.splay(u);
  102. col[u]^=1;
  103. lct.pushup(u);
  104. }
  105. else
  106. {
  107. lct.Access(u);
  108. lct.splay(u);
  109. printf("%d\n",lct.p[u].rmn>n?-1:lct.p[u].rmn);
  110. }
  111. }
  112. return 0;
  113. }

  

SPOJ 2939 QTREE5 LCT的更多相关文章

  1. SPOJ QTREE5 lct

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

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

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

  3. spoj 375 query on a tree LCT

    这道题是树链剖分的裸题,正在学LCT,用LCT写了,发现LCT代码比树链剖分还短点(但我的LCT跑极限数据用的时间大概是kuangbin大神的树链剖分的1.6倍,所以在spoj上是850ms卡过的). ...

  4. SPOJ OTOCI 动态树 LCT

    SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...

  5. SPOJ - OTOCI LCT

    OTOCI Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/problem/viewProblem. ...

  6. SPOJ QTREE4 lct

    题目链接 这个题已经处于花式tle了,改版后的spoj更慢了.. tle的话就多交几把... #include <iostream> #include <fstream> #i ...

  7. SPOJ QTREE3 lct

    题目链接 题意: 给定n个点 q个询问 以下n-1行给出树边,点有黑或白色.初始化为白色 以下q行: 询问有2种: 1. 0 x 把x点黑变白,白变黑 2.1 x 询问Path(1,x)路径上第一个黑 ...

  8. SPOJ QTREE2 lct

    题目链接 题意: 给一棵树.有边权 1.询问路径的边权和 2.询问沿着路径的第k个点标. 思路:lct裸题. #include <iostream> #include <fstrea ...

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

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

随机推荐

  1. 安装python的pip库setup.py出现报错的解决过程

    错误起因: 第一次安python3.72的时候,直接去官网下了压缩包,解压后也没有exe文件.环境也是手动配置,在之后安装Pycharm的时候,系统找不到解释器,手动加上. 错误经过: 等写程序用到i ...

  2. 十八、Nand Flash驱动和Nor Flash驱动

    在读者学习本章之前,最好了解Nand Flash读写过程和操作,可以参考:Nand Flash裸机操作. 一开始想在本章写eMMC框架和设备驱动,但是没有找到关于eMMC设备驱动具体写法,所以本章仍继 ...

  3. Python yield 使用浅析【转】

    Python yield 使用浅析 IBM developerWorks 中国 : Open source IBM 开源 - IBM Developer 中国 (原 developerWorks 中国 ...

  4. jmeter中生成UUID作为唯一标识符

    在测试过程中,我们有时候需要一个唯一不重复的值(比如order_id).我之前一直用的时间戳+计数器/随机函数拼接,但是有时候效果不太好,今天知道了UUID这玩意,可以来操作下.jmeter也提供了U ...

  5. Django 报错总结

    报错: AttributeError: 'NoneType' object has no attribute 'split' 最近在写网站中遇到一个问题,就是题目上所写的:AttributeError ...

  6. 【转载】Sqlserver限制最大可使用内存

    在Sqlserver的使用过程中,我们会发现随着运行时间的增长,Sqlserver占用的系统也越来越大,查了网上的相关资料说,Sqlserver在查询完相应数据后,为了下一次查询的性能,并不会马上释放 ...

  7. OS X系统特有文件目录说明

    os x特有的目录 OS X系统中,除了标准的unix目录外,还增加了特有的目录. /Applications 应用程序目录,默认所有的GUI应用程序都安装在这里: /Library 系统的数据文件. ...

  8. PLSQL Developer新建表空间

    转自:https://www.cnblogs.com/juddhu/archive/2012/03/20/2408499.html 通过pl/sql登录到Oracle数据库上,然后执行菜单:文件/新建 ...

  9. Python中with用法详解

    一 .with语句的原理 上下文管理协议(Context Management Protocol):包含方法 __enter__()和__exit__(),支持该协议的对象要实现这两个方法. 上下文管 ...

  10. 【深度学习】Precision 和 Recall 评价指标理解

    1. 四种情况 Precision精确率, Recall召回率,是二分类问题常用的评价指标.混淆矩阵如下: 预测结果为阳性 Positive 预测结果为假阳性 Negative 预测结果是真实的 Tr ...