CodeForces 343D 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
题意:给出一棵树,定义三种操作
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(树链剖分)的更多相关文章
- Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序
Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...
- 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 ...
- Water Tree(树链剖分+dfs时间戳)
Water Tree http://codeforces.com/problemset/problem/343/D time limit per test 4 seconds memory limit ...
- CF343D Water Tree 树链剖分
问题描述 LG-CF343D 题解 树剖,线段树维护0-1序列 yzhang:用珂朵莉树维护多好 \(\mathrm{Code}\) #include<bits/stdc++.h> usi ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- Codeforces 343D Water Tree & 树链剖分教程
原题链接 题目大意 给定一棵根为1,初始时所有节点值为0的树,进行以下三个操作: 将以某点为根的子树节点值都变为1 将某个节点及其祖先的值都变为0 *询问某个节点的值 解题思路 这是一道裸的树链剖分题 ...
- 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 ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
随机推荐
- zabbix 报警方式之 微信公众号报警(5)
一.条件 首先你得有一个微信公众号,并且是可以有发送消息的接口.然后你得有个脚本去调用微信的api. 这里感谢一下微信.使我们运维人员的报警方式多了一种... (同事们不要怪我哈.) 之后可以参考下z ...
- JavaScript中的可枚举属性与不可枚举属性
在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的.可枚举性决定了这个属性能否被for…in查找遍历到. 一.怎么判断属性是否可枚举 js中基本包 ...
- Tkinter Dimensions
Tkinter Dimensions: 各种长度,宽度,和其他部件的尺寸可以在许多不同的单位描述 各种长度,宽度,和其他部件的尺寸可以在许多不同的单位描述. 如果您设置了尺寸为整数,它被假定为 ...
- 读《分布式一致性原理》JAVA客户端API操作2
创建节点 通过客户端API来创建一个数据节点,有一下两个接口: public String create(final String path, byte data[], List<ACL> ...
- Vue之cookie操作(原生)
Vue之cookie操作(原生) 再vue组件中加入以下几个方法,然后调用即可. methods:{ //读取cookie,需要注意的是cookie是不能存中文的,如果需要存中文,解决方法是后端先进行 ...
- Django X 和 druid
依托于实际项目和生产环境互联网产品的总结积累,继承和扩展Xadmin,DjangoX 努力做 Django 框架的优秀实践项目 https://github.com/JoneXiong/DjangoX ...
- Spring Boot实践——三种拦截器的创建
引用:https://blog.csdn.net/hongxingxiaonan/article/details/48090075 Spring中的拦截器 在web开发中,拦截器是经常用到的功能.它可 ...
- 调用EF的存储过程报“存储区数据提供程序返回的数据读取器所具有的列数对于所请求的查询不够”问题
在运用Entity Framework调用存储过程的时候,遇到"调用EF的存储过程报"调用EF的存储过程报“存储区数据提供程序返回的数据读取器所具有的列数对于所请求的查询不够”问题 ...
- shell编程——日志输出的同时显屏
在执行脚本的时候我们常常需要将执行过程全部输出到日志里,以备出现报错时可以跟踪分析,开始我用的是exec: exec 1>info.log #把全部执行过程输出到info日志中 exec 2&g ...
- 关于PHP如何用实现防止用户在浏览器上使用后退功能重复提交输入
$(function(){ if(window.history && window.history.pushState){ $(window).on('popstate',functi ...