Codeforces343D(SummerTrainingDay06-F dfs序+线段树)
D. Water Tree
Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a reservoir which can be either empty or filled with water.
The vertices of the tree are numbered from 1 to n with the root at vertex 1. For each vertex, the reservoirs of its children are located below the reservoir of this vertex, and the vertex is connected with each of the children by a pipe through which water can flow downwards.
Mike wants to do the following operations with the tree:
- Fill vertex v with water. Then v and all its children are filled with water.
- Empty vertex v. Then v and all its ancestors are emptied.
- Determine whether vertex v is filled with water at the moment.
Initially all vertices of the tree are empty.
Mike has already compiled a full list of operations that he wants to perform in order. Before experimenting with the tree Mike decided to run the list through a simulation. Help Mike determine what results will he get after performing all the operations.
Input
The first line of the input contains an integer n (1 ≤ n ≤ 500000) — the number of vertices in the tree. Each of the following n - 1 lines contains two space-separated numbers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — the edges of the tree.
The next line contains a number q (1 ≤ q ≤ 500000) — the number of operations to perform. Each of the following q lines contains two space-separated numbers ci (1 ≤ ci ≤ 3), vi (1 ≤ vi ≤ n), where ci is the operation type (according to the numbering given in the statement), and vi is the vertex on which the operation is performed.
It is guaranteed that the given graph is a tree.
Output
For each type 3 operation print 1 on a separate line if the vertex is full, and 0 if the vertex is empty. Print the answers to queries in the order in which the queries are given in the input.
Examples
input
5
1 2
5 1
2 3
4 2
12
1 1
2 3
3 1
3 2
3 3
3 4
1 2
2 4
3 1
3 3
3 4
3 5
output
0
0
0
1
0
1
0
1
这颗树具有一个重要的特性,当一个点是 0 的时候,这个点的全部祖先一定都是 0;一点是 1,这个点的全部子孙都是 1。
利用这个性质,如果我们要把一个节点以及他的祖先都变成 0,我们只要把这个点标记成 0 就可以了——因为这样就包含了所有的操作信息。这种观点下,再看这三种操作。
- u 点以及 u 点的所有子孙都赋值为 1:这个时候应该先看一看子孙有没有 0,如果有 0,那么说明 u 的祖先都是应该是 0 但是还没表现出来。所以我们把 u 的父亲标记成 0。这之后,我们再把所有的子孙赋值成 1。
- u 点以及 u 点的所有祖先都赋值为 0:u 标记成 0;
- 查询一个点 u 的值:u 以及 u 的所以子孙的标记都不是 0,u 才真正的是 1。
这样一看,好开心,这三种操作都变成了树上的单点修改或者是一整个子树的整体修改。这个解决起来就很套路了,我们把树按照 dfs 序展开,就变成了线段树连续区间修改的问题。
//2017-09-01
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson (id<<1)
#define rson ((id<<1)|1) using namespace std; const int N = ; int head[N], tot;
struct Edge{
int to, next;
}edge[N<<]; void init(){
tot = ;
memset(head, -, sizeof(head));
} void add_edge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} int in[N], out[N], fa[N], cnt;
void dfs(int u, int father){
in[u] = ++cnt;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(v != father){
fa[v] = u;
dfs(v, u);
}
}
out[u] = cnt;
} bool flag;
struct Node{
int l, r, value, lazy;
}tree[N<<]; void build(int id, int l, int r){
tree[id].l = l;
tree[id].r = r;
tree[id].value = ;
tree[id].lazy = ;
if(l == r)return;
int mid = (tree[id].l+tree[id].r)>>;
build(lson, l, mid);
build(rson, mid+, r);
} void push_up(int id){
if(tree[lson].value && tree[rson].value)tree[id].value = ;
else tree[id].value = ;
} void push_down(int id){
if(tree[id].lazy){
tree[lson].value = tree[rson].value = tree[id].lazy;
tree[lson].lazy = tree[rson].lazy = tree[id].lazy;
tree[id].lazy = ;
}
} void update(int id, int l, int r, int op){
if(l == )return;
if(l <= tree[id].l && tree[id].r <= r){
if(tree[id].value == )flag = ;
tree[id].value = op;
if(op == )tree[id].lazy = op;
return;
}
push_down(id);
int mid = (tree[id].l+tree[id].r)>>;
if(l <= mid)update(lson, l, r, op);
if(r > mid)update(rson, l, r, op);
push_up(id);
} void query(int id, int l, int r){
if(l <= tree[id].l && tree[id].r <= r){
if(tree[id].value == )flag = ;
return;
}
push_down(id);
int mid = (tree[id].l+tree[id].r)>>;
if(l <= mid)query(lson, l, r);
if(r > mid)query(rson, l, r);
} int n, q; int main()
{
//freopen("inputF.txt", "r", stdin);
while(scanf("%d", &n) != EOF){
init();
int u, v;
for(int i = ; i < n-; i++){
scanf("%d%d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
fa[] = ;
cnt = ;
dfs(, );
build(, , n);
scanf("%d", &q);
while(q--){
scanf("%d%d", &u, &v);
if(u == ){
flag = ;
update(, in[v], out[v], );
if(!flag)update(, in[fa[v]], in[fa[v]], );
}else if(u == ){
update(, in[v], in[v], );
}else{
flag = ;
query(, in[v], out[v]);
if(flag)printf("1\n");
else printf("0\n");
}
}
} return ;
}
Codeforces343D(SummerTrainingDay06-F dfs序+线段树)的更多相关文章
- F - Change FZU - 2277 (DFS序+线段树)
题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- CodeForces 877E Danil and a Part-time Job(dfs序+线段树)
Danil decided to earn some money, so he had found a part-time job. The interview have went well, so ...
- 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...
- 【cf343】D. Water Tree(dfs序+线段树)
传送门 题意: 给出一个以\(1\)为根的有根树,起始每个结点都为\(0\),现在有三种操作: 1.将\(v\)及\(v\)的子树都置为\(1\): 2.将\(v\)及其所有的祖先都置为\(0\): ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
随机推荐
- 【062有新题】OCP 12c 062出现大量之前没有的新考题-16
choose one Which users are created and can be used for database and host management of your DBaaS da ...
- 题解 P5091 【【模板】欧拉定理】
欧拉定理:若 \(gcd(a,n)=1\),\(a^{\varphi(n)}\equiv 1(mod\ n)\) 设 \(1\sim n-1\) 中与 \(n\) 互素的 \(\varphi(n)\) ...
- spring boot实现异步调用
今天在这里学习下使用springboot的异步调用async 首先使用@EnableAsync开启异步功能 /** * @author fengzp * @date 17/5/8 * @email f ...
- mongoose 基础api 图表整理
一.背景 今天看 mongoose 的基础 API,参考了下面的链接做了图表以供查阅. 参考资料: http://www.cnblogs.com/xiaohuochai/p/7215067.html ...
- SpringBoot配置文件application.properties详解
喜欢的朋友可以关注下,粉丝也缺. 相信很多的码友在接触springboot时,不知道怎么去配置一些项目中需要的配置,比如数据源,tomcat调优,端口等等,下面我就给大家奉献出一些项目中常用的配置信息 ...
- Unity项目接入应用宝SDK实现截图功能
Unity项目接入应用宝SDK实现截图功能 问题由来 点击应用宝悬浮窗 如图所示 左下角有一个截图按钮 需要解决那些问题 截图信息需要由游戏引擎提供 SDK获取截图信息为同步 但是Unity引擎没有提 ...
- JS: 数组的循环函数
JS 数组相关的循环函数,用得挺多,所以有些坑还是要去踩一下,先来看一道面试题. 注意:下面提到的不改变原数组仅针对基本数据类型. 面试题 模拟实现数组的 map 函数. 心中有答案了吗?我的答案放在 ...
- [Umbraco] 自定义DataType中Data Editor Setting Type
上一篇介绍了在定义Document Type中的属性时用到的Data Type,当使用dropdown list如何调用外部数据源,可以根据提供的数据连接字符串,sql语句就能实现你想要显示的数据. ...
- (转)WebSphere的web工程中怎么获取数据源
原文:http://aguu125.iteye.com/blog/1694313 https://blog.csdn.net/bigtree_3721/article/details/44900325 ...
- 第一个WCF程序
WCF的服务需要寄宿在进程中,我们把服务端的叫做宿主,为服务指定宿主指定的过程叫服务寄宿.有两种方式一种是自我寄宿(Self-Hosting),一种是IIS寄宿方式.Self-Hosting我们通过一 ...