[SP16549]QTREE6
题意
给你一棵n个点的树,编号1~n。每个点可以是黑色,可以是白色。初始时所有点都是黑色。支持两种操作:
0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥有相同的颜色
1 u:翻转u的颜色
sol
第一问其实就是问u所在的同色连通块的大小。
有一种很直接的想法就是,维护两种颜色的\(LCT\),在每一种颜色的\(LCT\)中把同色连通块\(link\)起来。
这样一次操作的复杂度是与度数相关的,然后菊花树就被卡掉了吧。
把原树当做是一棵以1为根的有根树,我们考虑把一个点的颜色附到连接他的父亲的那条边上,这样每次修改操作就只涉及到一条边。
这样同色的点在这棵树上依旧是一个连通块。
但是一个连通块并不一定同色。
因为这个连通块的\(LCA\)不一定是同色呀。
所以特判一下就好了。
即如果是同色就直接输出\(LCA\)中存的值,否则输出\(LCA\)在splay中的右儿子存的值(因为\(LCA\)肯定是最浅的点也就是splay中中序遍历最靠前的点)。
code
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 1e5+5;
int n,m,col[N],fa[N];
vector<int>G[N];
struct LCT{
int fa[N],ch[2][N],sum[N],sz[N];
bool son(int x){return x==ch[1][fa[x]];}
bool isroot(int x)
{
return x!=ch[0][fa[x]]&&x!=ch[1][fa[x]];
}
void pushup(int x)
{
sum[x]=sum[ch[0][x]]+sum[ch[1][x]]+sz[x]+1;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],c=son(x);
ch[c][y]=ch[c^1][x];if (ch[c][y]) fa[ch[c][y]]=y;
fa[x]=z;if (!isroot(y)) ch[son(y)][z]=x;
ch[c^1][x]=y;fa[y]=x;pushup(y);
}
void splay(int x)
{
for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
if (!isroot(y)) son(x)^son(y)?rotate(x):rotate(y);
pushup(x);
}
void access(int x)
{
for (int y=0;x;y=x,x=fa[x])
{
splay(x);sz[x]+=sum[ch[1][x]];
ch[1][x]=y;sz[x]-=sum[ch[1][x]];
pushup(x);
}
}
int findroot(int x)
{
access(x);splay(x);
while (ch[0][x]) x=ch[0][x];
splay(x);return x;
}
void link(int x,int y)
{
if (!y) return;
access(y);splay(y);splay(x);
fa[x]=y;sz[y]+=sum[x];pushup(y);
}
void cut(int x,int y)
{
if (!y) return;
access(x);splay(x);
ch[0][x]=fa[ch[0][x]]=0;pushup(x);
}
}T[2];
void dfs(int u,int f)
{
for (int i=0,sz=G[u].size();i<sz;++i)
{
int v=G[u][i];if (v==f) continue;
T[0].link(v,u);fa[v]=u;
dfs(v,u);
}
}
int main()
{
n=gi();
for (int i=1;i<n;++i)
{
int u=gi(),v=gi();
G[u].push_back(v);G[v].push_back(u);
}
dfs(1,0);
m=gi();
while (m--)
{
int opt=gi(),u=gi();
if (opt) T[col[u]].cut(u,fa[u]),col[u]^=1,T[col[u]].link(u,fa[u]);
else{
T[col[u]].access(u);int ff=T[col[u]].findroot(u);
if (col[ff]==col[u]) printf("%d\n",T[col[u]].sum[ff]);
else printf("%d\n",T[col[u]].sum[T[col[u]].ch[1][ff]]);
}
}
return 0;
}
[SP16549]QTREE6的更多相关文章
- 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)
洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...
- SP16549 QTREE6 - Query on a tree VI(LCT)
题意翻译 题目描述 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥 ...
- SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块
\(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...
- LCT总结——应用篇(附题单)(LCT)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--概念篇戳这里 题单 灰常感谢XZY巨佬提供的强力资磁!(可参考XZY巨佬的博客总结) 题单对于系 ...
- LCT题单(自己的做题情况反馈)(转自Flash)
LCT题单(自己的做题情况反馈)(转自Flash) 随时进Flash Hu的LCT看一发 也可以看一下我自己的风格的板子 开始 维护链信息(LCT上的平衡树操作) [X] 洛谷P3690 [模板]Li ...
- QTREE6&&7 - Query on a tree VI &&VII
树上连通块 不用具体距离,只询问连通块大小或者最大权值 可以类比Qtree5的方法,但是记录东西很多,例如子树有无0/1颜色等 一个trick,两个LCT分离颜色 每个颜色在边上. 仅保留连通块顶部不 ...
- 【SPOJ】QTREE6(Link-Cut-Tree)
[SPOJ]QTREE6(Link-Cut-Tree) 题面 Vjudge 题解 很神奇的一道题目 我们发现点有黑白两种,又是动态加边/删边 不难想到\(LCT\) 最爆力的做法,显然是每次修改单点颜 ...
- QTREE6 - Query on a tree VI 解题报告
QTREE6 - Query on a tree VI 题目描述 给你一棵\(n\)个点的树,编号\(1\)~\(n\).每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我 ...
- [QTree6]Query on a tree VI
Description: 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括 ...
随机推荐
- Python 8 协程/异步IO
协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来 ...
- loadrunner之脚本篇——将内容保存为参数
在VuGen中默认使用{}的字符串称为参数 注意:参数必须在双引号中才能用 将字符串保存为参数 lr_save_string("string you want to save", ...
- Django---view视图FBV&CBV
一:创建项目和应用: 或者用命令创建: 1:django-admin.py startproject CBV&FBV 2: cd CBV&FBV (路径切到该文件夹下) 3: pyth ...
- Python编程-多态、封装、特性
一.多态与多态性 1.多态 (1)什么是多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 序列类型有多种形态:字符串,列表,元组. 动物有多种形态:人,狗,猪 文 ...
- redis 第一篇
一.redis简介 redis是一个开源的高性能键值对数据库:本质上是数据结构服务器或者是数据结构数据库 特点: 1.共享内存 如果有自己的线程可以读list,如果外界还有一个程序都上面的list,那 ...
- RabbitMQ死信队列
关于RabbitMQ死信队列 死信队列 听上去像 消息“死”了 其实也有点这个意思,死信队列 是 当消息在一个队列 因为下列原因: 消息被拒绝(basic.reject/ basic.nac ...
- input ajax自动补全
页面 <div class="manage-Car-add-info-sn"> <p style="width:25%; height:70%;floa ...
- 针对oracle集群的连接配置
Java连接oracle数据库集群的配置:<DB NAME="WFS" DRIVER="oracle.jdbc.driver.OracleDriver" ...
- 介绍一下Hibernate的二级缓存
介绍一下Hibernate的二级缓存 按照以下思路来回答:(1)首先说清楚什么是缓存,(2)再说有了hibernate的Session就是一级缓存,即有了一级缓存,为什么还要有二级缓存,(3)最后再说 ...
- Codeforces Round #374 (Div. 2) D. Maxim and Array 线段树+贪心
D. Maxim and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...