洛谷题目传送门

思路分析

题意就是要维护同色连通块大小。要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结。

至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次更改时暴力修改父边和子边。。。。。。

来个菊花图吧!(话说我真的好弱,前几天ZJOI的时候才知道对于某点度数很大的树/图有这样的称呼,真是很形象哈23333)

既然这条路行不通,那就换一种模型吧。

这是一种高级的维护染色连通块的较为通用的模型。

感觉蒟蒻对这种模型的理解与许多巨佬有不一样的地方,在这儿瞎扯扯吧

很多与树有关的题目,当边权不好处理时,有时候会转化为此边子节点的点权处理。

因为有根树中除了根,每个点都有唯一的父边。

在这一题里,道理是一样的,但转化方向却是反的,要把点化为边!

把每个点的父边赋予该点的颜色。我们需要两个LCT,每种对应一个颜色。一条边只有在对应颜色的LCT中才会被连上。

于是,原来同色点的连通块,就变成了剪开顶端节点后的边的连通块(解释一下,因为点的颜色给了父边,那么既然是顶端节点,那它的父边就不会在连通块中,也就是这个点与连通块不同色,于是该点的所有子树不能连起来,于是要剪掉)

然后就可以惊讶地发现,修改一个点的颜色之后,只要在原来颜色对应LCT中断掉父边,再在新颜色对应LCT中连接父边,就可以轻而易举地维护连通块啦。

再谈查询,上面提到了要剪开顶端节点(也就是连通块构成的树的树根),于是先findroot,再输出它的重子树的大小。

一个小细节,1节点是没有父亲的,不过为了模型的建立,要有父边,于是需要加一个虚点,让1的父亲指向它连边。

#include<cstdio>
#include<cstdlib>
#define R register int
#define I inline void
const int N=1000009,M=N<<1;
#define lc c[x][0]
#define rc c[x][1]
#define C col[u]
int fa[N],he[N],ne[M],to[M];
bool col[N];
struct LCT{
int f[N],c[N][2],si[N],s[N],h[N];
bool r[N];
LCT(){for(R i=1;i<N;++i)s[i]=1;}//注意初始化
inline bool nroot(R x){return c[f[x]][0]==x||c[f[x]][1]==x;}
I pushup(R x){
s[x]=s[lc]+s[rc]+si[x]+1;
}
I rotate(R x){
R y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k];
if(nroot(y))c[z][c[z][1]==y]=x;c[x][!k]=y;c[y][k]=w;
f[w]=y;f[y]=x;f[x]=z;
pushup(y);
}
I splay(R x){
R y;
while(nroot(x)){
if(nroot(y=f[x]))rotate((c[f[y]][0]==y)^(c[y][0]==x)?x:y);
rotate(x);
}
pushup(x);
}
I access(R x){
for(R y=0;x;x=f[y=x]){
splay(x);
si[x]+=s[rc];
si[x]-=s[rc=y];
}
}
inline int findroot(R x){
access(x);splay(x);
while(lc)x=lc;
splay(x);
return x;
}
I link(R x){//只传一个参数,因为只会连父边,cut同理
splay(x);//不用access(x),因为x一定是连通块的根
R y=f[x]=fa[x];
access(y);splay(y);//与常规LCT不同,别忘加
si[y]+=s[x];s[y]+=s[x];
}
I cut(R x){
access(x);splay(x);
lc=f[lc]=0;
pushup(x);
}
}lct[2];
void dfs(R x){
for(R y,i=he[x];i;i=ne[i])
if((y=to[i])!=fa[x])
fa[y]=x,dfs(y),lct[0].link(y);
}
#define G ch=getchar()
#define in(z) G;\
while(ch<'-')G;\
z=ch&15;G;\
while(ch>'-')z*=10,z+=ch&15,G
int main(){
register char ch;
R p=1,n,m,i,u,v,op;
in(n);
for(i=1;i<n;++i){
in(u);in(v);
to[++p]=v;ne[p]=he[u];he[u]=p;
to[++p]=u;ne[p]=he[v];he[v]=p;
}
dfs(1);
fa[1]=n+1;lct[0].link(1);//虚点
in(m);
while(m--){
in(op);in(u);
if(op)lct[C].cut(u),lct[C^=1].link(u);
else{
v=lct[C].findroot(u);
printf("%d\n",lct[C].s[lct[C].c[v][1]]);
}
}
return 0;
}

洛谷SP16549 QTREE6 - Query on a tree VI(LCT)的更多相关文章

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

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

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

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

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

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

  4. 洛谷SP16580 QTREE7 - Query on a tree VII(LCT,multiset)

    洛谷题目传送门 思路分析 维护子树最值还是第一次写QwQ 因为子树的最值会变化,所以不能简单地把最值记下来,还要维护一个平衡树,把每个子树的最大值扔进去,来资磁插入.删除和查询最值. 然后我就懒得手写 ...

  5. [QTree6]Query on a tree VI

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

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

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

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

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

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

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

  9. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

随机推荐

  1. 微信小程序开发 [05] wx.request发送请求和妹纸图

    1.wx.request 微信小程序中用于发起网络请求的API就是wx.request了,具体的参数太多,此处就不再一一详举了,基本使用示例如下: wx.request({ url: 'test.ph ...

  2. jquery操作checked

    jquery操作checkbox,如何获取勾选状态?如何使得勾选?如何取消勾选? 来段代码就知道了: <html> <head> <meta charset=" ...

  3. 数字IC设计入门书单

    首发于观芯志 写文章     数字IC设计入门书单 Forever snow   1 年前 作者:Forever snow链接:你所在领域的入门书单? - 知乎用户的回答来源:知乎著作权归作者所有,转 ...

  4. win7下mysql免安装版使用

    1.下载. 下载地址:http://downloads.mysql.com/archives/get/file/mysql-5.6.17-winx64.zip. 2.解压MySQL压缩包 解压到指定目 ...

  5. RESTful API设计概要

    一.简介 1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fiel ...

  6. 10、MySQL 的复制

    10.1 复制的概述 10.2 配置复制 10.3 复制的原理 有两种 1.基于sql语句的复制:传输数据少(sql语句文件),就能复制大量的数据,不过由于一些自定义的函数问题,会有一些限制: 2.基 ...

  7. 【python笔记】使用matplotlib,pylab进行python绘图

    一提到python绘图,matplotlib是不得不提的python最著名的绘图库,它里面包含了类似matlab的一整套绘图的API.因此,作为想要学习python绘图的童鞋们就得在自己的python ...

  8. JAVA 静态方法和实例方法的区别 (图表)

    静态方法和实例方法的区别主要体现在两个方面:   在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式.而实例方法只有后面这 ...

  9. Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries

    目录 上篇回顾 Building Queries 匹配所有的查询 全文查询 Full Text Queries 什么是全文查询? Match 全文查询 API 列表 基于词项的查询 Term Term ...

  10. Flutter - 给App增加启动屏幕(Splash Screen)并且设置背景颜色

    先看一下效果图,启动图最好设置为png格式的透明图,以防图片填充不满的时候背景图会非常的煞白(Flutter 默认背景色是白色). 打开android\app\src\main\res\drawabl ...