SP16549 QTREE6 - Query on a tree VI(LCT)
题意翻译
题目描述
给你一棵n个点的树,编号1~n。每个点可以是黑色,可以是白色。初始时所有点都是黑色。下面有两种操作请你操作给我们看:
0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥有相同的颜色
1 u:翻转u的颜色
输入格式
一行一个整数n
接下来n-1行,每行两个整数表示一条边
接下来一行一个整数m表示操作次数
接下来m行,每行两个整数分别表示操作类型和被操作节点 输出格式
对每个询问操作输出相应的结果
题解
简单来说,就是维护同色联通块的大小
干脆直接暴力linkcut好了(T上天)
然后来介绍一下(刚学会的)一种维护染色联通块的较为常用的模型
很多与树有关的题目,当边权不好处理时,可以把边权转化为儿子的点权来做
然后这里恰恰相反,要把点权给转化为边权
我们把每一个节点的颜色赋给与它父亲相连的边
弄两个LCT,对应两种颜色,一种颜色的边只有在对应的LCT中才会相连
于是,同色的联通块,就转化为了减去顶部节点后的边的连通块(因为顶部节点在这个LCT是没有向上连边的,说明顶部节点并不是这个颜色,那么他的所有子树并不连通,要断开才行)
然后可以发现,修改点的颜色之后,只要在原来的LCT中cut,在新的LCT上link就行啦
查询怎么做呢?先access,然后findroot,再输出root的实子树大小就行了
ps:1本来没有父亲,但为了方便,可以建一个虚点n+1,令他作为1的父亲就好了
//minamoto
#include<iostream>
#include<cstdio>
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=;
int f[N],Next[N<<],head[N],ver[N<<],tot,col[N],n,m;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
}
struct LCT{
int fa[N],ch[N][],si[N],sum[N];
LCT(){for(int i=;i<=n+;++i) sum[i]=;}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
#define lc ch[x][0]
#define rc ch[x][1]
inline void pushup(int x){sum[x]=sum[lc]+sum[rc]+si[x]+;}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pushup(y);
}
void splay(int x){
for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
if(!isroot(y))
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=;x;x=fa[y=x]){
splay(x);
si[x]+=sum[rc];
si[x]-=sum[rc=y];
}
}
int findroot(int x){
access(x),splay(x);
while(lc) x=lc;
splay(x);
return x;
}
void link(int x){
access(x),splay(x);
int y=fa[x]=f[x];
access(y),splay(y);
si[y]+=sum[x],sum[y]+=sum[x];
}
void cut(int x){
access(x),splay(x);
lc=fa[lc]=;
pushup(x);
}
}lct[];
void dfs(int u){
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v==f[u]) continue;
f[v]=u,dfs(v),lct[].link(v);
}
}
int main(){
//freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<n;++i){
int u=read(),v=read();
add(u,v);
}
dfs();
f[]=n+,lct[].link();
m=read();
while(m--){
int op=read(),u=read();
if(op) lct[col[u]].cut(u),lct[col[u]^=].link(u);
else{
int v=lct[col[u]].findroot(u);
print(lct[col[u]].sum[lct[col[u]].ch[v][]]);
}
}
Ot();
return ;
}
SP16549 QTREE6 - Query on a tree VI(LCT)的更多相关文章
- 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)
洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...
- SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块
\(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...
- SP16580 QTREE7 - Query on a tree VII(LCT)
题意翻译 一棵树,每个点初始有个点权和颜色(输入会给你) 0 u:询问所有u,v路径上的最大点权,要满足u,v路径上所有点颜色相同 1 u:反转u的颜色 2 u w:把u的点权改成w 题解 Qtree ...
- QTREE5 - Query on a tree V(LCT)
题意翻译 你被给定一棵n个点的树,点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的边个数. 一开始所有的点都是黑色的. 要求作以下操作: 0 i 将点i的颜 ...
- SP2666 QTREE4 - Query on a tree IV(LCT)
题意翻译 你被给定一棵n个点的带边权的树(边权可以为负),点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的权值之和. 一开始所有的点都是白色的. 要求作以下 ...
- 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上所有节点(包括 ...
- SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」
题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连 ...
- BZOJ3637 Query on a tree VI(树链剖分+线段树)
考虑对于每一个点维护子树内与其连通的点的信息.为了换色需要,记录每个点黑白两种情况下子树内连通块的大小. 查询时,找到深度最浅的同色祖先即可,这可以比较简单的树剖+线段树乱搞一下(似乎就是qtree3 ...
随机推荐
- Linux实战教学笔记38:企业级Nginx Web服务优化实战(下)
四,Nginx站点目录及文件URL访问控制 4.1 根据扩展名限制程序和文件访问 Web2.0时代,绝大多数网站都是以用户为中心多的,例如:bbs,blog,sns产品,这几个产品都有一个共同特点,就 ...
- 01-nginx介绍及编译安装
第一天的时候学过apache,nginx和apache一样都是一个WEB服务器.也就是说你的网站之所以可以在网上运行,总得有一台机器在为你提供服务,这台机器就是服务器.这台服务器通过什么软件在为你提供 ...
- shell if,case,for,while语法
#shell if的语法 if [空格 xxx 空格] then echo xxxxx exit 1/2/3/4/.... 0表示正确. elif [空格 xxx 空格] then echo xxxx ...
- cs4.1 编译与安装
cs4.1编译报 https://issues.apache.org/jira/browse/CLOUDSTACK-2913 cs4.1安装报
- spring4-5-事务管理
1.简单介绍 事务管理是企业级应用程序开发中必不可少的技术, 用来确保数据的完整性和一致性. 事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用 事务的 ...
- ubuntu 16.04 nfs服务的搭建
nfs服务是实现Linux和Linux之间的文件共享,nfs服务的搭建比较简单. 现在介绍如何在ubuntu16.04系统中搭建nfs服务,ubuntu的搭建比红帽的还要简单. 1.安装nfs服务 s ...
- excel判断新增使用字典作为页面级数据库,减少io
前提:该机构录入的都是和该机构有关的数据,机构下的funmental(idcard唯一)和creditinfo(funmentalid唯一)不能重复所以推出以下结论:1.根据userid(机构)=&g ...
- js关系图库:aworkflow
auto-workflow 用于快速构建各种关系图的库,比如流程图,可视化执行流等 github地址:https://github.com/auto-workflow/AWorkflow 快速开始 n ...
- 金士顿DT100 G3 PS2251-07海力士U盘量产修复成功教程
金士顿DT100 G3这款U盘.用了大概一年半没什么问题,前段时间拷贝大文件,无奈电脑突然断电,然后这个U盘在电脑上就读不出来了,只能显示盘符,所以有了修复过程. 最开始我也是菜鸟,不知道怎么搞, ...
- ScreenCapturePro2 for Joomla_3.4.7-tinymce4x
1.1. 与Joomla_3.4.7-tinymce4x整合 示例下载:Joomla_3.4.7, 1.1.1. 添加screencapture文件夹 1.1.2. 2.添加插件文件夹 路径: ...