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

题意:给出一棵树,定义三种操作

1 将u的子树修改为1

2 将u及其所有祖先修改为0

3 查询树上标号为u的点的值

题解:非常裸的树链剖分,连push_up都不用,嗯,就是这样。

代码如下:

#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson root<<1
#define rson root<<1|1
using namespace std; struct node
{
int l,r,sum,lazy;
}tr[];
vector<int> g[];
int deep[],size[],fa[],son[],id[],top[],cnt; void push_down(int root)
{
int mid=(tr[root].l+tr[root].r)>>;
tr[lson].sum=tr[root].lazy*(mid-tr[root].l+);
tr[lson].lazy=tr[root].lazy;
tr[rson].sum=tr[root].lazy*(tr[root].r-mid);
tr[rson].lazy=tr[root].lazy;
tr[root].lazy=-;
} void build(int root,int l,int r)
{
if(l==r)
{
tr[root].l=l;
tr[root].r=r;
tr[root].lazy=-;
tr[root].sum=;
return ;
}
tr[root].l=l;
tr[root].r=r;
tr[root].lazy=-;
int mid=(l+r)>>;
build(lson,l,mid);
build(rson,mid+,r);
} void update(int root,int l,int r,int val)
{
if(tr[root].l==l&&tr[root].r==r)
{
tr[root].sum=val;
tr[root].lazy=val;
return ;
}
if(~tr[root].lazy)
{
push_down(root);
}
int mid=(tr[root].l+tr[root].r)>>;
if(mid<l)
{
update(rson,l,r,val);
}
else
{
if(mid>=r)
{
update(lson,l,r,val);
}
else
{
update(lson,l,mid,val);
update(rson,mid+,r,val);
}
}
} int query(int root,int l,int r)
{
if(tr[root].l==l&&tr[root].r==r)
{
return tr[root].sum;
}
if(~tr[root].lazy)
{
push_down(root);
}
int mid=(tr[root].l+tr[root].r)>>;
if(mid<l)
{
return query(rson,l,r);
}
else
{
if(mid>=r)
{
return query(lson,l,r);
}
else
{
return query(lson,l,mid)+query(rson,mid+,r);
}
}
} void dfs1(int now,int f,int dep)
{
fa[now]=f;
size[now]=;
deep[now]=dep;
int maxson=-;
for(int i=;i<g[now].size();i++)
{
if(g[now][i]==f)
{
continue;
}
dfs1(g[now][i],now,dep+);
size[now]+=size[g[now][i]];
if(size[g[now][i]]>maxson)
{
maxson=size[g[now][i]];
son[now]=g[now][i];
}
}
} void dfs2(int now,int topf)
{
id[now]=++cnt;
top[now]=topf;
if(!son[now])
{
return ;
}
dfs2(son[now],topf);
for(int i=;i<g[now].size();i++)
{
if(g[now][i]==son[now]||g[now][i]==fa[now])
{
continue;
}
dfs2(g[now][i],g[now][i]);
}
} void sub_update(int x)
{
update(,id[x],id[x]+size[x]-,);
} void path_update(int u,int v)
{
while(top[u]!=top[v])
{
if(deep[top[u]]<deep[top[v]])
{
swap(u,v);
}
update(,id[top[u]],id[u],);
u=fa[top[u]];
}
if(deep[u]>deep[v])
{
swap(u,v);
}
update(,id[u],id[v],);
} int main()
{
int n;
scanf("%d",&n);
for(int i=;i<n;i++)
{
int from,to;
scanf("%d%d",&from,&to);
g[from].push_back(to);
g[to].push_back(from);
}
dfs1(,,);
dfs2(,);
build(,,n);
int m;
scanf("%d",&m);
while(m--)
{
int kd,u;
scanf("%d%d",&kd,&u);
if(kd==)
{
sub_update(u);
}
else
{
if(kd==)
{
path_update(,u);
}
else
{
printf("%d\n",query(,id[u],id[u]));
}
}
}
}

CodeForces 343D water tree(树链剖分)的更多相关文章

  1. Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序

    Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...

  2. Codeforces Round #200 (Div. 1) D. Water Tree 树链剖分+线段树

    D. Water Tree time limit per test 4 seconds memory limit per test 256 megabytes input standard input ...

  3. Water Tree(树链剖分+dfs时间戳)

    Water Tree http://codeforces.com/problemset/problem/343/D time limit per test 4 seconds memory limit ...

  4. CF343D Water Tree 树链剖分

    问题描述 LG-CF343D 题解 树剖,线段树维护0-1序列 yzhang:用珂朵莉树维护多好 \(\mathrm{Code}\) #include<bits/stdc++.h> usi ...

  5. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  6. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  7. Codeforces 343D Water Tree & 树链剖分教程

    原题链接 题目大意 给定一棵根为1,初始时所有节点值为0的树,进行以下三个操作: 将以某点为根的子树节点值都变为1 将某个节点及其祖先的值都变为0 *询问某个节点的值 解题思路 这是一道裸的树链剖分题 ...

  8. CodeForces 916E Jamie and Tree(树链剖分+LCA)

    To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...

  9. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

随机推荐

  1. OpenStack--Cinder(G版)中的volume type

    一.volume type的相关操作 Cinder中的卷类型,是卷的一种标识,各个OpenStack的发行者可根据自身对系统的约束来定义卷类型的使用.G版的Cinder中与卷类型相关的两种资源:typ ...

  2. 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...

  3. lunix,命令集锦

    1. ls命令 ls命令是列出目录内容(List Directory Contents)的意思.运行它就是列出文件夹里的内容,可能是文件也可能是文件夹. ? 1 2 3 4 5 6 7 root@te ...

  4. 【Oracle】Oracle透明网关访问MSSQLServer

             Oracle 数据库的透明网关 ( transparent gateway )是这样的一个接口:通过它,我们可以 sqlplus 操纵其他数据库,如 MS SQLServer . s ...

  5. 关于电机驱动扩展板 L293D 马达板Arduino

    注意端口3,4,5,6,7,8,9,10,11,12会被占用(板子上的pin口). 通过 MS_DCMotor motor(4); 中的4指的是4号电机,同理还有1-3号电机.不是pin口   舵机用 ...

  6. leetcode529

    public class Solution { //DFS public char[,] UpdateBoard(char[,] board, int[] click) { ), n = board. ...

  7. IOS数据持久化存储之SQLite3第三方库FMDB的使用

    SQLite是一种小型的轻量级的关系型数据库,在移动设备上使用是非常好的选择,无论是Android还是IOS,都内置了SQLite数据库,现在的版本都是SQLite3.在IOS中使用SQLite如果使 ...

  8. 第1章WCF简介(WCF全面解析读书笔记2)

    第1章 WCF简介 面向服务架构(SOA)是近年来备受业界关注的一个主题,它代表了软件架构的一种方向.顺应SOA发展潮流,微软于2006年年底推出了一种新的分布式通信框架Windows Communi ...

  9. Linux实战教学笔记45:NoSQL数据库之redis持久化存储(一)

    第1章 redis存储系统 1.1 redis概述 REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统.redis和大名鼎鼎的Mem ...

  10. 这几天用高通VUFORIA的体会

    VUFORIA 主要用来做图像识别,先把图片上至网站,然后网站分析生成数据包 在UNITY中导入VUFORIA SDK和数据包后,就可以正常使用了 对了,数据包需要勾选Load Active那个选项, ...