bzoj3637: Query on a tree VI
Description
You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are numbered from 1 to n.
Each node has a color, white or black. All the nodes are black initially.
We will ask you to perfrom some instructions of the following form:
- 0 u : ask for how many nodes are connected to u, two nodes are connected iff all the node on the path from u to v (inclusive u and v) have a same color.
- 1 u : toggle the color of u(that is, from black to white, or from white to black).
Input
The first line contains a number n denoted how many nodes in the tree(1 ≤ n ≤ 105). The next n - 1 lines, each line has two numbers (u, v) describe a edge of the tree(1 ≤ u, v ≤ n). The next line contains a number m denoted how many operations we are going to process(1 ≤ m ≤ 105). The next m lines, each line describe a operation (t, u) as we mentioned above(0 ≤ t ≤ 1, 1 ≤ u ≤ n).
Output
For each query operation, output the corresponding result.
Sample Input
1 2
1 3
1 4
1 5
3
0 1
1 1
0 1
Sample Output
1
题解:
先将树定个根,然后建立黑白两棵lct
对于黑树,时刻满足如果有边u-v,则v一定是黑点(u不一定是黑点)
且对于黑树上的某个点,记录一下通过虚边和它相连的黑点有多少,lct上维护这条链的总和,白树同理
对于单点改色,假如它是黑点,要在黑树上把它和它父亲节点断开,然后再在白树上把它和它父亲节点连起来,白点同理
对于单点查询,假如它是黑点,把它access上去后要判断这条链最上面的那个点是不是黑点,不是就要输出最上面那个点的儿子节点,白点同理
code:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
const int maxn=;
const int maxm=;
int n,q,op,a,b,tot,now[maxn],son[maxm],pre[maxm],col[maxn],fa[maxn];
bool flag[maxn];
struct LCT{
int id,fa[maxn],son[maxn][],tot[maxn],sum[maxn];
void init(int x,int op){tot[x]+=op,sum[x]+=op;}
int which(int x){return son[fa[x]][]==x;}
bool isroot(int x){return son[fa[x]][]!=x&&son[fa[x]][]!=x;}
void update(int x){
sum[x]=tot[x];
if (son[x][]) sum[x]+=sum[son[x][]];
if (son[x][]) sum[x]+=sum[son[x][]];
}
void rotate(int x){
int y=fa[x],z=fa[y],d=which(x),dd=which(y);
fa[son[x][d^]]=y,son[y][d]=son[x][d^],fa[x]=fa[y];
if (!isroot(y)) son[z][dd]=x;
fa[y]=x,son[x][d^]=y,update(y),update(x);
}
void splay(int x){
while (!isroot(x)){
if (isroot(fa[x])) rotate(x);
else if (which(fa[x])==which(x)) rotate(fa[x]),rotate(x);
else rotate(x),rotate(x);
}
}
void access(int x){
for (int p=;x;x=fa[x]){
splay(x);
if (son[x][]) tot[x]+=sum[son[x][]];
if (p) tot[x]-=sum[p];
son[x][]=p,update(p=x);
}
}
void cut(int x,int y){
if (!y) return;
access(x),splay(x),fa[son[x][]]=,son[x][]=,update(x);
}
void link(int x,int y){
if (!y) return;
access(y),splay(y),splay(x),fa[x]=y,son[y][]=x,update(y);
}
int find_left(int x){for (access(x),splay(x);son[x][];x=son[x][]); return x;}
void query(int x){
int t=find_left(x); splay(t);
printf("%d\n",col[t]==id?sum[t]:sum[son[t][]]);
}
}T[];
void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
void add(int a,int b){put(a,b),put(b,a);}
void dfs(int u){
for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if (v!=fa[u]) fa[v]=u,T[].link(v,u),dfs(v);
}
int main(){
read(n),T[].id=,T[].id=;
for (int i=;i<n;i++) read(a),read(b),add(a,b);
for (int i=;i<=n;i++) col[i]=;
for (int i=;i<=n;i++) T[].init(i,);
dfs();
for (read(q);q;q--){
read(op),read(a);
if (op) T[col[a]].cut(a,fa[a]),T[col[a]].init(a,-),col[a]^=,T[col[a]].init(a,),T[col[a]].link(a,fa[a]);
else T[col[a]].query(a);
}
return ;
}
bzoj3637: Query on a tree VI的更多相关文章
- BZOJ3637 Query on a tree VI(树链剖分+线段树)
考虑对于每一个点维护子树内与其连通的点的信息.为了换色需要,记录每个点黑白两种情况下子树内连通块的大小. 查询时,找到深度最浅的同色祖先即可,这可以比较简单的树剖+线段树乱搞一下(似乎就是qtree3 ...
- 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 ...
- QTREE6 - Query on a tree VI 解题报告
QTREE6 - Query on a tree VI 题目描述 给你一棵\(n\)个点的树,编号\(1\)~\(n\).每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我 ...
- bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解
题意: 一棵n个节点的树,节点有黑白两种颜色,初始均为白色.两种操作:1.更改一个节点的颜色;2.询问一个节点所处的颜色相同的联通块的大小. 思路: 1.每个节点记录仅考虑其子树时,假设其为黑色时所处 ...
- SPOJ QTREE Query on a tree VI
You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...
- [BZOJ 3637]Query on a tree VI
偶然看见了这题,觉得自己 QTREE.COT 什么的都没有刷过的真是弱爆了…… 一道思路很巧妙的题,终于是在约大爷的耐心教导下会了,真是太感谢约大爷了. 这题显然是树链剖分,但是链上维护的东西很恶心. ...
- QTREE6&&7 - Query on a tree VI &&VII
树上连通块 不用具体距离,只询问连通块大小或者最大权值 可以类比Qtree5的方法,但是记录东西很多,例如子树有无0/1颜色等 一个trick,两个LCT分离颜色 每个颜色在边上. 仅保留连通块顶部不 ...
- 2019.02.17 spoj Query on a tree VI(链分治)
传送门 题意简述:给你一棵nnn个黑白点的树,支持改一个点的颜色,询问跟某个点颜色相同的连通块大小. 思路: 还是链分治 233 记fi,0/1f_{i,0/1}fi,0/1表示iii的所有颜色为0 ...
- [CodeChef-QTREE6]Query on a tree VI
题目大意: 给你一棵黑白树,每个点默认是白色,要求支持以下两种操作: 1.改变一个点的颜色: 2.除去连接不同颜色的点的边,求某个点连通块的大小. 思路: 对原树维护两个树链剖分, 一棵维护当点x为白 ...
随机推荐
- UVa10886 Standard Deviation
留坑(p.345) 这是什么意思 暴力? 然而那些有两个人跑的那么快是为什么?(有个人竟然是陈锋...)
- 「S-A-L-T-A」项目失败总结!
前言: 从2013年8月20日进入这个项目开始,到现在12月12日. 从项目详细设计开始,到现在连SI2阶段的疏通测试都没有完成! (现在,这个项目好像已经不需要我们再做下去了...) 项目失败原因总 ...
- Windows Media Player axWindowsMediaPlayer1 分类: C# 2014-07-28 12:04 195人阅读 评论(0) 收藏
属性/方法名: 说明: [基本属性] URL:String; 指定媒体位置,本机或网络地址 uiMode:String; 播放器界面模式,可为Full, Mini, None, Invisible p ...
- eclipse GWT开发环境的离线布置方法
安装方法http://blog.csdn.net/u011029071/article/details/10143841 用eclipse自动更新安装失败N次,还是得手动来 以Google Plugi ...
- 单元测试时候使用[ClassInitialize]会该方法必须是静态的公共方法,不返回值并且应采用一个TestContext类型的参数报错的解决办法
using Microsoft.VisualStudio.TestTools.UnitTesting; 如果该DLL应用的是 C:\Program Files\Microsoft Visual Stu ...
- C#自定义泛型类绑定ComboBox控件
C# WinForm ComboBox 自定义数据项 (ComboBoxItem ) WinForm下的ComboBox默认是以多行文本来设定显示列表的, 这通常不符合大家日常的应用, 因为大家日常应 ...
- wikioi 2573 大顶堆与小顶堆并用
题目描写叙述 Description 我们使用黑匣子的一个简单模型.它能存放一个整数序列和一个特别的变量i.在初始时刻.黑匣子为空且i等于0. 这个黑匣子能运行一系列的命令.有两类命令: ADD(x) ...
- android 01
安卓开源(就是免费),谷歌收购后推出,可以山寨(小米,三星都是安卓的山寨),ios不是开源(苹果应用要商用就要交钱).安卓3.0是平板,现在安卓至少是4.0以上,否则out了. 微软主要是系统和off ...
- RHCA-RH442-Linux系统性能调优 (学习)
RHCA-RH442-Linux系统性能调优
- Qt 学习之路 :Qt Quick Controls
自 QML 第一次发布已经过去一年多的时间,但在企业应用领域,QML 一直没有能够占据一定地位.很大一部分原因是,QML 缺少一些在企业应用中亟需的组件,比如按钮.菜单等.虽然移动领域,这些组件已经变 ...