SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块
\(\color{#0066ff}{ 题目描述 }\)
给你一棵n个点的树,编号1~n。每个点可以是黑色,可以是白色。初始时所有点都是黑色。下面有两种操作请你操作给我们看:
0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥有相同的颜色
1 u:翻转u的颜色
\(\color{#0066ff}{输入格式}\)
一行一个整数n
接下来n-1行,每行两个整数表示一条边
接下来一行一个整数m表示操作次数
接下来m行,每行两个整数分别表示操作类型和被操作节点
\(\color{#0066ff}{输出格式}\)
对每个询问操作输出相应的结果
\(\color{#0066ff}{输入样例}\)
5
1 2
1 3
1 4
1 5
3
0 1
1 1
0 1
\(\color{#0066ff}{输出样例}\)
5
1
\(\color{#0066ff}{数据范围与提示}\)
对所有数据,\(1\leq n \leq 10^5\),\(1\leq m \leq 10^5\)
\(\color{#0066ff}{ 题解 }\)
容易想到,开两个LCT分别维护黑白两种颜色
然后修改颜色的时候,暴力cut相邻的边,link相邻的边
然而。。。存在一种东东叫菊花图。。。
显然很容易就被Hack掉了
正常LCT的题目中,如果有边权,我们肯定是边权转到点权上,这样才好维护
然而。。。本题就是与众不同,他要把点权转到边权上!
把每个点的点权转到它与父亲的边上,特别的,开一个0号节点,\(0-1\)存的是1的点权
然后询问的联通块即为所在联通块根的siz-1,注意,根的颜色跟其它点不同
因为根父亲的边不在这里!
因此仍然是LCT维护子树大小即可
对于改变颜色的问题,发现只需要断一条边即可
所以复杂度就保证了
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e5 + 10;
struct LCT {
protected:
struct node {
node *ch[2], *fa;
int siz, tot;
node(int siz = 0, int tot = 1): siz(siz), tot(tot) { ch[0] = ch[1] = fa = NULL; }
void upd() {
tot = siz + 1;
if(ch[0]) tot += ch[0]->tot;
if(ch[1]) tot += ch[1]->tot;
}
bool ntr() { return fa && (fa->ch[0] == this || fa->ch[1] == this); }
bool isr() { return fa->ch[1] == this; }
}pool[maxn];
void rot(node *x) {
node *y = x->fa, *z = y->fa;
bool k = x->isr(); node *w = x->ch[!k];
if(y->ntr()) z->ch[y->isr()] = x;
(x->ch[!k] = y)->ch[k] = w;
(y->fa = x)->fa = z;
if(w) w->fa = y;
y->upd(), x->upd();
}
void splay(node *o) {
while(o->ntr()) {
if(o->fa->ntr()) rot(o->isr() ^ o->fa->isr()? o : o->fa);
rot(o);
}
}
void access(node *x) {
for(node *y = NULL; x; x = (y = x)->fa) {
splay(x);
if(x->ch[1]) x->siz += x->ch[1]->tot;
if((x->ch[1] = y)) x->siz -= y->tot;
x->upd();
}
}
node *findroot(node *o) {
access(o), splay(o);
while(o->ch[0]) o = o->ch[0];
return splay(o), o;
}
public:
void link(int l, int r) {
node *x = pool + l, *y = pool + r;
access(x), splay(x);
x->fa = y;
access(y), splay(y);
y->siz += x->tot;
y->upd();
}
void cut(int l, int r) {
node *x = pool + l;
access(x), splay(x);
x->ch[0] = x->ch[0]->fa = NULL;
x->upd();
}
int query(int p) {
node *o = findroot(pool + p);
return o->ch[1]->tot;
}
}s[2];
struct node {
int to;
node *nxt;
node(int to = 0, node *nxt = NULL): to(to), nxt(nxt) {}
};
node *head[maxn];
int n, m, f[maxn], col[maxn];
void add(int from, int to) {
head[from] = new node(to, head[from]);
}
void dfs(int x, int fa) {
f[x] = fa;
s[1].link(x, fa);
for(node *i = head[x]; i; i = i->nxt)
if(i->to != fa)
dfs(i->to, x);
}
int main() {
n = in();
int x, y;
for(int i = 1; i <= n; i++) col[i] = 1;
for(int i = 1; i < n; i++) x = in(), y = in(), add(x, y), add(y, x);
dfs(1, 0);
for(m = in(); m --> 0;) {
x = in(), y = in();
if(x == 0) printf("%d\n", s[col[y]].query(y));
if(x == 1) s[col[y]].cut(y, f[y]), s[col[y] ^= 1].link(y, f[y]);
}
return 0;
}
SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块的更多相关文章
- SP16549 QTREE6 - Query on a tree VI(LCT)
题意翻译 题目描述 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥 ...
- 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)
洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...
- 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$ 去暴力删边连 ...
- SPOJ QTREE6 Query on a tree VI 树链剖分
题意: 给出一棵含有\(n(1 \leq n \leq 10^5)\)个节点的树,每个顶点只有两种颜色:黑色和白色. 一开始所有的点都是黑色,下面有两种共\(m(1 \leq n \leq 10^5) ...
- bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解
题意: 一棵n个节点的树,节点有黑白两种颜色,初始均为白色.两种操作:1.更改一个节点的颜色;2.询问一个节点所处的颜色相同的联通块的大小. 思路: 1.每个节点记录仅考虑其子树时,假设其为黑色时所处 ...
- BZOJ 3637: Query on a tree VI LCT_维护子树信息_点权转边权_好题
非常喜欢这道题. 点权转边权,这样每次在切断一个点的所有儿子的时候只断掉一条边即可. Code: #include <cstring> #include <cstdio> #i ...
- 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 ...
随机推荐
- JCTF 2014(Misc)
小试身手: 点击下载附件 res/raw/hehe,打开 得到flag
- 本地测试html文件时CSS效果显示, 但是当django的服务器上运行时效果不显示
本地测试时各种效果都显示, 但是当在django服务器上测试时, 效果却不显示, 原因是我将css文件放在一个static文件夹里, 没有在settings中设置static_dir选项.将stati ...
- paramiko远程执行命令成功
- 问题:只能在执行 Render() 的过程中调用 RegisterForEventValidation;结果:只能在执行 Render() 的过程中调用 RegisterForEventValidation
只能在执行 Render() 的过程中调用 RegisterForEventValidation 当在导出Execl或Word的时候,会发生只能在执行 Render() 的过程中调用 Register ...
- 6-EasyNetQ之订阅
一个EasyNetQ订阅者订阅一种消息类型(消息类为.NET 类型).通过调用Subcribe方法一旦对一个类型设置了订阅,一个持久化队列就会在RabbitMQ broker上被创建,这个类型的任何消 ...
- 【270】IDL处理GeoTIFF数据
参考:将原GeoTIFF数据的投影坐标信息赋值到新创建的文件上 pro tiff_projection ;启动ENVI e = ENVI(/HEADLESS) ;打开文件 file = 'D:\01- ...
- MSSQL 日期查询 包含NULL值
方一: 以下做法保证数据里面没有NULL值 '') '') '') '') exec sp_executesql N'select ide_code as ''系统编号'',name as ''申请专 ...
- FOUC
如果使用import方法对CSS进行导入,会导致某些页面在Windows 下的Internet Explorer出现一些奇怪的现象:以无样式显示页面内容的瞬间闪烁,这种现象称之为文档样式短暂失效(Fl ...
- linux下vtune使用
安装:http://www.cnblogs.com/jiu0821/p/5943533.html 终端输入amplxe-gui,打开vtune界面. 点击new project,进入project p ...
- C++——override
override关键字作用: 如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译.举例子说明 struct Base { virtual ...