Water Tree CodeForces - 343D(dfs序列+线段树 模板)

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.

题目大意:现在有一个n点的树,然后每个点初始都是没有水的,然后有两种操作,一种操作是将该点以及子树的点全部加满水,一种是将该点以及所有父亲节点抽出水,然后查询某个点是否有水

解题思路:首先要对树进行dfs序,然后排序好之后按照按照线段树进行单点查询和单点修改和区间修改,对于加水这个操作,我们可以区间修改,然后对于抽水我们只需要单点修改即可,至于查询的时候,我们只要查询这个点所在的子树中是否有抽水的标记即可,那么在加水的操作中我们只需要增加检查是否有抽水的标记,要是有的话,我们就把这个点的父亲节点标记为抽水

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
//strattime:2017/10/18 11:04
//endtime:2017/10/18 21:07

const int MAXN = 5e5+10;
vector tu[MAXN];
struct node
{
	int val,flag;
}tree[MAXN*4];
int in[MAXN],out[MAXN],fa[MAXN];
int flag,n,q,cnt;
void dfs(int son,int father)
{
	int i,k;
	in[son]=++cnt;
	for(i=0;i


你可能感兴趣的:(ACM,线段树,模板题)