Description

Mad scientist Mike has constructed a rooted tree, which consists of nnvertices. Each vertex is a reservoir which can be either empty or filled with water.

The vertices of the tree are numbered from 1 to nn 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 vv with water. Then vv and all its children are filled with water.

  2. Empty vertex vv . Then vv and all its ancestors are emptied.

  3. Determine whether vertex vv 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-1n−1 lines contains two space-separated numbers \(a_{i}, b_{i}\) ( \(1<=a_{i},b_{i}<=n, a_{i}≠b_{i}\) ) — 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 \(c_{i}( 1<=c_{i}<=3\) ), \(v_{i}\)( \(1<=v_{i}<=n\) ), where \(c_{i}\) is the operation type (according to the numbering given in the statement), and \(v_{i}\) 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.

你不需要理解题意,你只需要知道,这是一个树剖裸题(虽然我没一遍切。)

支持三种操作(初始值全部为\(0\))

  • 1.将节点\(v\)及其子树赋值为\(1\).
  • 2.将节点\(v\)到根节点\(1\)的路径上的点的值置为\(0\).
  • 3.查询当前节点\(v\)的值。(只会为\(0\)或\(1\))

对于每个操作\(3\),输出一行。(具体见代码好了

这是一个不完整的树剖,我没建树,有没用到反\(dfs\)序。 emmm

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define R register using namespace std; const int gz=500001; inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int head[gz],tot,n,m; struct cod{int u,v;}edge[gz<<1]; inline void add(R int x,R int y)
{
edge[++tot].u=head[x];
edge[tot].v=y;
head[x]=tot;
} int dfn[gz],idx,son[gz],f[gz],depth[gz],size[gz],top[gz]; void dfs1(R int u,R int fa)
{
f[u]=fa;depth[u]=depth[fa]+1;size[u]=1;
for(R int i=head[u];i;i=edge[i].u)
{
if(edge[i].v==fa)continue;
dfs1(edge[i].v,u);
size[u]+=size[edge[i].v];
if(son[u]==-1 or size[son[u]]<size[edge[i].v])
son[u]=edge[i].v;
}
} void dfs2(R int u,R int t)
{
dfn[u]=++idx;top[u]=t;
if(son[u]==-1)return ;
dfs2(son[u],t);
for(R int i=head[u];i;i=edge[i].u)
{
if(dfn[edge[i].v])continue;
dfs2(edge[i].v,edge[i].v);
}
} int tg[gz<<2],tr[gz<<2]; #define ls o<<1
#define rs o<<1|1 inline void down(R int o)
{
if(tg[o]==-1)return;
tg[ls]=tg[rs]=tg[o];
tr[ls]=tr[rs]=tr[o];
tg[o]=-1;
return ;
} void change(R int o,R int l,R int r,R int x,R int y,R int k)
{
if(x<=l and y>=r){tr[o]=tg[o]=k;return;}
down(o);
R int mid=(l+r)>>1;
if(x<=mid)change(ls,l,mid,x,y,k);
if(y>mid)change(rs,mid+1,r,x,y,k);
} int query(R int o,R int l,R int r,R int pos)
{
if(l==r)return tr[o];
down(o);
R int mid=(l+r)>>1;
if(pos<=mid)return query(ls,l,mid,pos);
else return query(rs,mid+1,r,pos);
} inline void tchange(R int x,R int y)
{
R int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(depth[fx]>depth[fy])
{
change(1,1,n,dfn[fx],dfn[x],0);
x=f[fx];
}
else
{
change(1,1,n,dfn[fy],dfn[y],0);
y=f[fy];
}
fy=top[y],fx=top[x];
}
if(dfn[x]>dfn[y])swap(x,y);
change(1,1,n,dfn[x],dfn[y],0);
return ;
} int main()
{
in(n);memset(son,-1,sizeof son);
for(R int i=1,x,y;i<n;i++)
{
in(x),in(y);
add(x,y),add(y,x);
}
dfs1(1,0);dfs2(1,1);memset(tg,-1,sizeof tg);
in(m);
for(R int i=1,opt,v;i<=m;i++)
{
in(opt);
switch(opt)
{
case 1:in(v);change(1,1,n,dfn[v],dfn[v]+size[v]-1,1);break;
case 2:in(v);tchange(1,v);break;
case 3:in(v);printf("%d\n",query(1,1,n,dfn[v]));break;
}
}
}

树链剖分【CF343D】Water Tree的更多相关文章

  1. 【BZOJ3626】LCA(树链剖分,Link-Cut Tree)

    [BZOJ3626]LCA(树链剖分,Link-Cut Tree) 题面 Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. ...

  2. 【BZOJ2157】旅游(树链剖分,Link-Cut Tree)

    [BZOJ2157]旅游(树链剖分,Link-Cut Tree) 题面 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥 ...

  3. 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree

    原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...

  4. 树链剖分 (求LCA,第K祖先,轻重链剖分、长链剖分)

      2020/4/30   15:55 树链剖分是一种十分实用的树的方法,用来处理LCA等祖先问题,以及对一棵树上的节点进行批量修改.权值和查询等有奇效. So, what is 树链剖分? 可以简单 ...

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

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

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

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

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

  8. CodeForces 343D water tree(树链剖分)

    Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...

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

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

  10. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

随机推荐

  1. 【转】如何解决每次打开office2010都会出现正在配置以及使用KMS

    转自:http://jingyan.baidu.com/article/90895e0fb1525964ec6b0bb5.html 一.使用mini-KMS_Activator_v1.2_Office ...

  2. 洛谷 P2501 [HAOI2006]数字序列 解题报告

    P2501 [HAOI2006]数字序列 题目描述 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. ...

  3. SqlServer中临时表的应用

    一.变通处理WHERE后面IN的参数过多 WHERE后面的条IN操作符里的参数比较小时,可以直接使用IN(1,2,3)这样处理,当个数不确定(可能超过1000)时,应该考虑使用临时表关联查询: SEL ...

  4. 正确答案 [Hash/枚举]

    正确答案 题目描述 小H与小Y刚刚参加完UOIP外卡组的初赛,就迫不及待的跑出考场对答案. "吔,我的答案和你都不一样!",小Y说道,"我们去找神犇们问答案吧" ...

  5. HDU 4417 划分树写法

    Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...

  6. nginx反向代理Tomcat/Jetty获取客户端IP地址

    使用nginx做反向代理,Tomcat服务器和Jetty服务器如何获取客户端真实IP地址呢?首先nginx需要配置proxy_set_header,这样JSP使用request.getHeader(& ...

  7. 串的模式匹配算法(求子串位置的定位函数Index(S,T,pos))

    串的模式匹配的一般方法如算法4.5(在bo4-1.cpp 中)所示:由主串S 的第pos 个字 符起,检验是否存在子串T.首先令i 等于 pos(i 为S 中当前待比较字符的位序),j 等于 1(j ...

  8. C# using一般用法 (转)

    using一般有着以下几种用法: 1.直接引入命名空间 a.using System ,这个是最常用的,就是using+命名空间,这样就可以直接使用命名空间中的类型,而免去了使用详细的命名空间 b.使 ...

  9. pageContext对象的用法详述

    pageContext对象  这个对象代表页面上下文,该对象主要用于访问JSP之间的共享数据. pageContext是PageContext类的实例,使用pageContext可以访问page.re ...

  10. 校内训练0609 problem c

    [题目大意] 给一棵树,求有多少条路径满足总和-最大值 是P的倍数 n<=10^5, P<=10^7 [题解] 一看就是点分治嘛 不考虑子树合并,考虑poj1741的做法,每次考虑经过重心 ...