Water Tree
Codeforces Round #200 (Div. 1) D:http://codeforces.com/problemset/problem/343/D
题意:给你一颗有根树,树的每个节点有一个装水的东西,然后付亲的水可以流向儿子。一开始树上每个节点都是空的,然后会有两种操作。1 v,表示把v节点为子树的每个点都灌满水,2 v,表示v及v的祖先都清空。3 v是询问 v节点是否为空,为空输出0,否则输出1.
题解:首先,树上操作可以通过DFS,然后转化成数组操作。3操作来说,只要v的子树中有一个0,那么v一定是0,所以把单点查询,转化成了区间查询。2操作来说,我们可以只进行单点更新,即只对v这个节点操作。1操作的时候,就是区间更新,但是这里首先要查询v中是否有0,因为2操作只到了点。加入说,之前 2 v,那么v及其父亲应该是0的,这时候如果1,v的话,那么必须要把v的父亲变为0.这里有两种实现。先说一种好写。set运用。我们一开始把树上的每个节点都放进set,表示每个几点都是0.对于操作1.来说,首先我们要查询是否有0,Q.lower_bound(ll[temp]),如果找到并且这个数的位置不超过rr[temp],那么v的父亲要变成0,即可v的父亲查到set中,同时把那些变成1的元素从set中删除,Q.erase(Q.lower_bound(ll[temp]),Q.upper_bound(rr[temp]));3操作类似。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
const int N=5e5+;
int head[N],now;
int fa[N],ll[N],rr[N],cnt;
set<int>Q;
void init(){
memset(head,-,sizeof(head));
memset(rr,,sizeof(rr));
memset(ll,,sizeof(ll));
memset(fa,,sizeof(fa));
now=;
cnt=;
}
struct Node{
int v;
int next;
}edge[N*];
void add(int u,int v){
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void DFS(int u,int f){
ll[u]=rr[u]=++now;
Q.insert(now);
fa[u]=f;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v!=f)
DFS(v,u);
}
rr[u]=now;
}
int n,m,t1,t2;
int main(){
while(~scanf("%d",&n)){
init();
for(int i=;i<n;i++){
scanf("%d%d",&t1,&t2);
add(t1,t2);add(t2,t1);
}
DFS(,);
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d%d",&t1,&t2);
if(t1==){
bool flag=false;
set<int>::iterator it=Q.lower_bound(ll[t2]);
if(it==Q.end()||(*it)>rr[t2])
flag=true;
Q.erase(Q.lower_bound(ll[t2]),Q.upper_bound(rr[t2]));
if(!flag&&t2!=)
Q.insert(ll[fa[t2]]);
}
else if(t1==){
Q.insert(ll[t2]);
}
else {
set<int>::iterator it=Q.lower_bound(ll[t2]);
if(it==Q.end()||(*it)>rr[t2])
printf("1\n");
else
printf("0\n");
}
}
}
}
第二种实现:线段树版本。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
const int N=5e5+;
int head[N],now;
int fa[N],ll[N],rr[N],cnt;
int n,m,t1,t2;
int lazy[N*],seg[N*];
void init(){
memset(head,-,sizeof(head));
memset(rr,,sizeof(rr));
memset(ll,,sizeof(ll));
memset(fa,,sizeof(fa));
memset(lazy,,sizeof(lazy));
memset(seg,,sizeof(seg));
now=;
cnt=;
}
struct Node{
int v;
int next;
}edge[N*];
void add(int u,int v){
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void DFS(int u,int f){
ll[u]=rr[u]=++now;
fa[u]=f;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v!=f)
DFS(v,u);
}
rr[u]=now;
}
void push_up(int rt){
seg[rt]=min(seg[rt<<],seg[rt<<|]);
}
void pushdown(int rt){
if(lazy[rt]>){
lazy[rt<<]=lazy[rt<<|]=lazy[rt];
seg[rt<<]=seg[rt<<|]=seg[rt];
lazy[rt]=-;
}
}
void update(int l,int r,int rt,int x,int y){
if(l==x&&y==r){
lazy[rt]=seg[rt]=;
return;
}
pushdown(rt);
int mid=(l+r)/;
if(mid>=y)update(l,mid,rt<<,x,y);
else if(mid<x)update(mid+,r,rt<<|,x,y);
else {
update(l,mid,rt<<,x,mid);
update(mid+,r,rt<<|,mid+,y);
}
push_up(rt);
}
void update1(int l,int r,int rt,int x){
if(l==r){
lazy[rt]=seg[rt]=;
return;
}
pushdown(rt);
int mid=(l+r)/;
if(mid>=x)update1(l,mid,rt<<,x);
else update1(mid+,r,rt<<|,x);
push_up(rt);
}
int query(int l,int r,int rt,int x,int y){
if(l==x&&r==y){
return seg[rt];
}
pushdown(rt);
int mid=(l+r)/;
if(mid>=y)return query(l,mid,rt<<,x,y);
else if(mid<x) return query(mid+,r,rt<<|,x,y);
else {
return min(query(l,mid,rt<<,x,mid),query(mid+,r,rt<<|,mid+,y));
}
} int main(){
while(~scanf("%d",&n)){
init();
for(int i=;i<n;i++){
scanf("%d%d",&t1,&t2);
add(t1,t2);add(t2,t1);
}
DFS(,);
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d%d",&t1,&t2);
if(t1==){
int temp=query(,now,,ll[t2],rr[t2]);
update(,now,,ll[t2],rr[t2]);
if(temp==&&t2!=)
update1(,now,,ll[fa[t2]]);
}
else if(t1==){
update1(,now,,ll[t2]);
}
else {
printf("%d\n",query(,now,,ll[t2],rr[t2]));
}
}
}
}
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 dfs序
D. Water Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/343/problem/ ...
- 【题解】Luogu CF343D Water Tree
原题传送门:CF343D Water Tree 这道题要用树链剖分,我博客里有对树链剖分的详细介绍 这明显是弱智题 树剖套珂朵莉树多简单啊 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自 ...
- 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 ...
- xtu summer individual 6 F - Water Tree
Water Tree Time Limit: 4000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Orig ...
- 343D/Codeforces Round #200 (Div. 1) D. Water Tree dfs序+数据结构
D. Water Tree Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- D. Water Tree
D. Water Tree time limit per test 4 seconds memory limit per test 256 megabytes input standard input ...
- Codeforces 343D Water Tree 分类: Brush Mode 2014-10-05 14:38 98人阅读 评论(0) 收藏
Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...
随机推荐
- EditText操作收集
1.android EditText插入字符串到光标所在位置 EditText mTextInput=(EditText)findViewById(R.id.input);//EditText对象 i ...
- LabVIEW设计模式系列——资源关闭后错误处理
标准: 1.很多引用资源其打开函数和关闭函数对错误处理的方式有所不同:2.一般地NI的Help里对打开函数的错误端子的解释是这样的:如错误发生在VI或函数运行之前,VI或函数将把错误输入值传递至错误输 ...
- mysql中enum的用法
字段 类型 长度/值*1 整理 属性 Null 默认2 额外 注释 enum 说明:enum类型的字段,若长度值写长度1/2,报错 (1) 数据长度为1,则为0,1,2… (2) ...
- iOS CoreData (1)
下面开始学习一下CoreData. Core Data不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS). Core Data 为数据变更管理.对象存储.对象读取恢复的功能提供了支持. 它 ...
- 我的插件のinput文本框实现宽度自适应
先来最后结果:DEMO 介绍一下如何让一个文本框的宽度能够随着文本框中的内容的宽度增长而增长,也就是能够实现宽度自适应效果. 代码实例如下: <!DOCTYPE html> <htm ...
- .Net开源SqlServer ORM框架SqlSugar整理
一.链接整理 官方Git源代码地址: https://github.com/sunkaixuan/SqlSugar 最新发布版更新地址:当前版本Release 3.5.2.1 https://gith ...
- <script runat=server>、<%%>和<%#%>的区别
①<script runat="server">代码段与<%%>内联代码段的区别 在asp.net页面的aspx文件中允许使用<script runa ...
- DataGridView 绑定 List
DataGridView 绑定 List<T> 不会自动更新 正确方式是将 List<T> 设置为 BindingList<T> 即可 (双向绑定)
- 如何在swift中实现oc中的分类
在oc中为了增强已有类的功能,我们经常使用分类.使用分类,我们可以在不破坏原有类的结构的前提下,对原有类进行模块化的扩展. 但是在swift中没有分类这种写法了.相对应的是swift中只有扩展(Ext ...
- hdu 1018 Big Number (数学题)
Problem Description Inmany applications very large integers numbers are required. Some of theseappli ...