D. Water Tree

time limit per test:4 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

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:

  1. Fill vertex v with water. Then v and all its children are filled with water.
  2. Empty vertex v. Then v and all its ancestors are emptied.
  3. 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 aibi (1 ≤ ai, bi ≤ nai ≠ 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 就可以了——因为这样就包含了所有的操作信息。这种观点下,再看这三种操作。

  1. u 点以及 u 点的所有子孙都赋值为 1:这个时候应该先看一看子孙有没有 0,如果有 0,那么说明 u 的祖先都是应该是 0 但是还没表现出来。所以我们把 u 的父亲标记成 0。这之后,我们再把所有的子孙赋值成 1。
  2. u 点以及 u 点的所有祖先都赋值为 0:u 标记成 0;
  3. 查询一个点 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序+线段树)的更多相关文章

  1. F - Change FZU - 2277 (DFS序+线段树)

    题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...

  2. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

  3. 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树

    题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...

  4. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

  5. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  6. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  7. 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 ...

  8. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

  9. 【cf343】D. Water Tree(dfs序+线段树)

    传送门 题意: 给出一个以\(1\)为根的有根树,起始每个结点都为\(0\),现在有三种操作: 1.将\(v\)及\(v\)的子树都置为\(1\): 2.将\(v\)及其所有的祖先都置为\(0\): ...

  10. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

随机推荐

  1. <转>(笔记)正则表达式的几种引擎

    这篇主要是基于<精通正则表达式>的一篇读书笔记,因为书还没看完,可能以后还会有相关的笔记.(工作以后看书的效率真的很低啊……) 正则引擎主要可以分为基本不同的两大类:一种是DFA(确定性有 ...

  2. Akka(42): Http:身份验证 - authentication, authorization and use of raw headers

    当我们把Akka-http作为数据库数据交换工具时,数据是以Source[ROW,_]形式存放在Entity里的.很多时候除数据之外我们可能需要进行一些附加的信息传递如对数据的具体处理方式等.我们可以 ...

  3. CSS中text-shadow的几个好看的文字demo及其代码

    最近有看到一些镂空的或者立体的文字设计图非常好看,然后想了想,应该是使用text-shadow来实现的,这里我贴出我仿的八个demo,分享给大家 首先是HTML代码 <div class=&qu ...

  4. [转载]windows下安装Python虚拟环境virtualenv,virtualenvwrapper-win

    1 前言 由于Python的版本众多,还有Python2和Python3的争论,因此有些软件包或第三方库就容易出现版本不兼容的问题. 通过 virtualenv 这个工具,就可以构建一系列 虚拟的Py ...

  5. [Leetcode]120.三角形路径最小和

    ---恢复内容开始--- 题目的链接 简单的动态规划题,使用了二维dp数组就能很好的表示. 由于有边界的问题,所以这个dp数组为 dp[n+1][n+1]. dp[i][j]意思是终点为(i-1,j- ...

  6. 剑指offer七之斐波那契数列

    一.题目 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.n<=39. 二.思路 序号:                  0  1   2   3  4   5  ...

  7. Java代码调用Oracle的存储过程,存储函数和包

    Java代码调用存储过程和存储函数要使用CallableStatement接口 查看API文档: 上代码: java代码调用如下的存储过程和函数: 查询某个员工的姓名  月薪 职位 create or ...

  8. RESTful SOA与DDD(领域驱动设计)

    视频地址:http://www.infoq.com/presentations/RESTful-SOA-DDD 作者的一个DDD采访:http://www.informit.com/articles/ ...

  9. win2003 远程连接限制

    1.单击开始->运行,输入gpedit.msc,打开组策略编辑器,找到计算机配置 ->管理模版 -> Windows组件 ->终端服务.把限制连接数量的属性修改成我们需要的数字 ...

  10. 数据库设计 Step by Step (2)——数据库生命周期

    引言:数据库设计 Step by Step (1)得到这么多朋友的关注着实出乎了我的意外.这也坚定了我把这一系列的博文写好的决心.近来工作上的事务比较繁重,加之我期望这个系列的文章能尽可能的系统.完整 ...