Description:

给你一棵n个点的树,编号1~n。每个点可以是黑色,可以是白色。初始时所有点都是黑色。下面有两种操作请你操作给我们看:

0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥有相同的颜色

1 u:翻转u的颜色

Hint:

\(n\le 10^5\)

Solution:

这题我一开始用树剖写,然后随机数据跑得飞快,交上去被菊花图卡飞23333333

树剖正解,详见https://www.cnblogs.com/ivorysi/p/10103010.html

但是.......树剖写法太毒瘤了!!!

所以这里介绍的是LCT做法

不得不说比较巧妙

考虑用2颗LCT维护两种颜色的联通块

并且把点的颜色存到边上

每次修改就在一颗LCT上断边,另一颗LCT上连这条边

同时LCT维护子树信息,询问直接搞就行了

我的LCT还是太菜了,看了好久才看懂

  1. #include <map>
  2. #include <set>
  3. #include <stack>
  4. #include <cmath>
  5. #include <queue>
  6. #include <cstdio>
  7. #include <cstring>
  8. #include <cstdlib>
  9. #include <iostream>
  10. #include <algorithm>
  11. #define ls p<<1
  12. #define rs p<<1|1
  13. using namespace std;
  14. typedef long long ll;
  15. const int mxn=1e6+5;
  16. int n,m,cnt=1;
  17. int f[mxn],hd[mxn],col[mxn];
  18. inline int read() {
  19. char c=getchar(); int x=0,f=1;
  20. while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
  21. while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
  22. return x*f;
  23. }
  24. inline void chkmax(int &x,int y) {if(x<y) x=y;}
  25. inline void chkmin(int &x,int y) {if(x>y) x=y;}
  26. struct ed {
  27. int to,nxt;
  28. }t[mxn<<1];
  29. inline void add(int u,int v) {
  30. t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
  31. }
  32. struct LCT {
  33. int fa[mxn],s[mxn],sz[mxn],ch[mxn][2];
  34. void push_up(int x) {
  35. sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+s[x]+1;
  36. }
  37. int isnotrt(int x) {
  38. return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
  39. }
  40. void rotate(int x) {
  41. int y=fa[x],z=fa[y],tp=ch[y][1]==x;
  42. if(isnotrt(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;
  43. ch[y][tp]=ch[x][tp^1]; fa[ch[x][tp^1]]=y;
  44. ch[x][tp^1]=y; fa[y]=x;
  45. push_up(y),push_up(x);
  46. }
  47. void splay(int x) {
  48. while(isnotrt(x)) {
  49. int y=fa[x],z=fa[y];
  50. if(isnotrt(y))
  51. (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
  52. rotate(x);
  53. }
  54. }
  55. void access(int x) {
  56. for(int y=0;x;x=fa[y=x]) {
  57. splay(x);
  58. s[x]+=sz[ch[x][1]];
  59. ch[x][1]=y;
  60. s[x]-=sz[ch[x][1]];
  61. }
  62. }
  63. int findrt(int x) {
  64. access(x); splay(x);
  65. while(ch[x][0]) x=ch[x][0];
  66. splay(x); return x;
  67. }
  68. void link(int x) {
  69. splay(x); fa[x]=f[x];
  70. int y=f[x]; access(y); splay(y);
  71. s[y]+=sz[x]; sz[y]+=sz[x];
  72. }
  73. void cut(int x) {
  74. access(x); splay(x);
  75. ch[x][0]=fa[ch[x][0]]=0;
  76. push_up(x);
  77. }
  78. }lct[2];
  79. void dfs(int u,int fa) {
  80. for(int i=hd[u];i;i=t[i].nxt) {
  81. int v=t[i].to;
  82. if(v==fa) continue ;
  83. dfs(v,u); f[v]=u; lct[0].link(v);
  84. }
  85. }
  86. int main()
  87. {
  88. n=read(); int u,v;
  89. for(int i=1;i<=n+1;++i) lct[0].sz[i]=lct[1].sz[i]=1; //千万不要忘记赋初值
  90. for(int i=1;i<n;++i) {
  91. u=read(); v=read();
  92. add(u,v); add(v,u);
  93. }
  94. dfs(1,0); f[1]=n+1; //1节点也必须有父亲
  95. lct[0].link(1); m=read();
  96. for(int i=1;i<=m;++i) {
  97. u=read(); v=read();
  98. if(u==1) lct[col[v]].cut(v),lct[col[v]^=1].link(v);
  99. else {
  100. int tp=lct[col[v]].findrt(v);
  101. printf("%d\n",lct[col[v]].sz[lct[col[v]].ch[tp][1]]);
  102. }
  103. }
  104. return 0;
  105. }

[QTree6]Query on a tree VI的更多相关文章

  1. QTREE6 - Query on a tree VI 解题报告

    QTREE6 - Query on a tree VI 题目描述 给你一棵\(n\)个点的树,编号\(1\)~\(n\).每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我 ...

  2. SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块

    \(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...

  3. 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)

    洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...

  4. SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」

    题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连 ...

  5. SP16549 QTREE6 - Query on a tree VI(LCT)

    题意翻译 题目描述 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥 ...

  6. SPOJ QTREE6 Query on a tree VI 树链剖分

    题意: 给出一棵含有\(n(1 \leq n \leq 10^5)\)个节点的树,每个顶点只有两种颜色:黑色和白色. 一开始所有的点都是黑色,下面有两种共\(m(1 \leq n \leq 10^5) ...

  7. bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解

    题意: 一棵n个节点的树,节点有黑白两种颜色,初始均为白色.两种操作:1.更改一个节点的颜色;2.询问一个节点所处的颜色相同的联通块的大小. 思路: 1.每个节点记录仅考虑其子树时,假设其为黑色时所处 ...

  8. bzoj 3637: Query on a tree VI 树链剖分 && AC600

    3637: Query on a tree VI Time Limit: 8 Sec  Memory Limit: 1024 MBSubmit: 206  Solved: 38[Submit][Sta ...

  9. QTREE6&&7 - Query on a tree VI &&VII

    树上连通块 不用具体距离,只询问连通块大小或者最大权值 可以类比Qtree5的方法,但是记录东西很多,例如子树有无0/1颜色等 一个trick,两个LCT分离颜色 每个颜色在边上. 仅保留连通块顶部不 ...

随机推荐

  1. C++设计模式——观察者模式(转)

    前言 之前做了一个性能测试的项目,就是需要对现在的产品进行性能测试,获得测试数据,然后书写测试报告,并提出合理化的改善意见.项目很简单,我们获得了一系列性能测试数据,对于数据,我们需要在Excel中制 ...

  2. logical_backup: expdp/impdp

    Table of Contents 1. 注意事项 2. 前期准备 3. 常用参数及示例 4. 常用语句示例 5. 交互式命令 6. 技巧 6.1. 不生成文件直接导入目标数据库 6.2. 通过she ...

  3. hexo+github page +markdown问题汇总

    1.没有权限提交 解决办法:把git版本由2.x改为1.9 未完待续

  4. Spring.Net 简单实例-01(IOC)

    1.话不多说看操作.新建"Windows窗体应用程序" 2:通过配置文件创建IOC容器 首先引入安装包 3:定义一个接口(更好的体现封装性,当然也可以直接使用类) 定义一个类,实现 ...

  5. python datetime.datetime is not JSON serializable

    1.主要是python  list转换成json时对时间报错:datetime.datetime(2014, 5, 23, 9, 33, 3) is not JSON serializable. 2. ...

  6. Install zeal on ubuntu16.04

    Dash is a helpful software for macOS users. For Windows and Linux users, zeal is the open-source cou ...

  7. 解决AS gradle下载同步卡慢的问题

    国内因为GFW的原因,导致同步谷歌等服务器的插件源非常非常慢,几乎是龟爬,还好有阿里云的镜像源,据说速度很快,还不快试试: 1.build.gradle里的buildscript和allproject ...

  8. IDEA 出现错误:找不到或无法加载主类

    idea本身缓存问题 解决:清理缓存重启IDEAfile-->invalidate Cache/restart 之后再重新build. 还不行的话,设置一下file-->project s ...

  9. 如何保证Redis的高可用

    什么是高可用 全年时间里,99%的时间里都能对外提供服务,就是高可用 主备切换 在master故障时,自动检测,将某个slave切换为master的过程,叫做主备切换.这个过程,实现了Redis主从架 ...

  10. debian 下deb包的制作

    http://page.renren.com/601230663/note/817856769?op=next&curTime=1333642042000