D. Water Tree
4 seconds
256 megabytes
standard input
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:
- 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.
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.
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.
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
0
0
0
1
0
1
0
1
思路:dfs序+线段树;
先dfs将点映射成线性的,然后维护两棵线段树,一个是往里面灌水的时间,一个是抽水的时间,抽水的时候是单点往上更新,因为这个点的
如果是某个点的字节点,那么查询这个这个父亲节点点所包含的子树时一点包含要更新的点,然后每个节点的灌水和抽水的最晚的时间就可以了,
然后两次查询比较时间先后就可以了。
复杂度n×log(n);
1 #include<stdio.h>
2 #include<math.h>
3 #include<queue>
4 #include<algorithm>
5 #include<string.h>
6 #include<iostream>
7 #include<stack>
8 #include<vector>
9 using namespace std;
10 typedef long long LL;
11 typedef vector<int>Ve;
12 vector<Ve>vec(600000);
13 int ans[600000];
14 int id[600000];
15 bool flag[600000];
16 int cn = 0;
17 int l[600000];
18 int r[600000];
19 int pre[600000];
20 void dfs(int n);
21 int tree1[600000*4];
22 int tree0[600000*4];
23 int query(int l,int r,int k,int nn,int mm,int *tr,int c);
24 void update(int l,int r,int k,int nn,int mm,int *tr,int i,int c);
25 int main (void)
26 {
27 int n,x,y;
28 scanf("%d",&n);
29 for(int i = 0; i < n-1; i++)
30 {
31 scanf("%d %d",&x,&y);
32 vec[x].push_back(y);
33 vec[y].push_back(x);
34 }
35 dfs(1);
36 for(int i = 1; i <= n; i++)
37 id[ans[i]] = i;
38 int m;
39 scanf("%d",&m);
40 int ccn = 0;
41 while(m--)
42 {
43 int val,c;
44 ++ccn;
45 scanf("%d %d",&val,&c);
46 if(val == 1)
47 {
48 update(l[c],r[c],0,1,cn,tree1,ccn,1);
49 //printf("%d\n",ccn);
50 }
51 else if(val == 2)
52 {
53 update(id[c],id[c],0,1,cn,tree0,ccn,0);
54 }
55 else
56 {
57 int a = query(id[c],id[c],0,1,cn,tree1,1);
58 int b = query(l[c],r[c],0,1,cn,tree0,0);
59 //printf("%d %d\n",a,b);
60 printf("%d\n",a>b);
61 }
62 }
63 return 0;
64 }
65 void dfs(int n)
66 {
67 flag[n] = true;
68 ans[++cn] = n;
69 l[n] = cn;
70 for(int i = 0; i < vec[n].size(); i++)
71 {
72 int ic = vec[n][i];
73 if(!flag[ic])
74 pre[ic] = n,dfs(ic);
75 }
76 r[n] = cn;
77 }
78 void update(int l,int r,int k,int nn,int mm,int *tr,int i,int c)
79 {
80 if(l > mm||r < nn)
81 {
82 return ;
83 }
84 else if(l <= nn&&r >= mm)
85 {
86 tr[k] = max(tr[k],i);
87 }
88 else
89 {
90 if(tr[k]&&c == 1)tr[2*k+1] = tr[k],tr[2*k+2] = tr[k],tr[k] = 0;
91 update(l,r,2*k+1,nn,(nn+mm)/2,tr,i,c);
92 update(l,r,2*k+2,(nn+mm)/2+1,mm,tr,i,c);
93 if(c == 0)
94 tr[k] = max(tr[k],tr[2*k+1]),tr[k] = max(tr[k],tr[2*k+2]);
95 }
96 }
97 int query(int l,int r,int k,int nn,int mm,int *tr,int c)
98 {
99 if(l > mm||r < nn)
100 {
101 return 0;
102 }
103 else if(l <= nn&&r >= mm)
104 {
105 return tr[k];
106 }
107 else
108 { if(c&&tr[k])tr[2*k+1] = tr[k],tr[2*k+2] = tr[k],tr[k] = 0;
109 int nx = query(l,r,2*k+1,nn,(nn+mm)/2,tr,c);
110 int ny = query(l,r,2*k+2,(nn+mm)/2+1,mm,tr,c);
111 return max(nx,ny);
112 }
113 }
D. 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:把 ...
- 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 ...
随机推荐
- 深入了解scanf() getchar()和gets()等函数之间的区别
scanf(), getchar()等都是标准输入函数,一般人都会觉得这几个函数非常简单,没什么特殊的.但是有时候却就是因为使用这些函数除了问题,却找不出其中的原因.下面先看一个很简单的程序: 程序1 ...
- mysql-centos8下安装
参考文章 1.下载安装包 客服端与服务端 依赖包 2.linux下检查是否安装 rpm -qa | grep -i mysql 安装过会显示软件名称,没安装过就是空的 3.安装包传到虚拟机 先需要把安 ...
- Hbase(6)【Java Api Phoenix操作Hbase】
目录 两种方式操作Phoenix 1.Thick Driver 2.Thin Driver 3.注意事项 两种方式操作Phoenix 官网:http://phoenix.apache.org/faq. ...
- 大数据学习day18----第三阶段spark01--------0.前言(分布式运算框架的核心思想,MR与Spark的比较,spark可以怎么运行,spark提交到spark集群的方式)1. spark(standalone模式)的安装 2. Spark各个角色的功能 3.SparkShell的使用,spark编程入门(wordcount案例)
0.前言 0.1 分布式运算框架的核心思想(此处以MR运行在yarn上为例) 提交job时,resourcemanager(图中写成了master)会根据数据的量以及工作的复杂度,解析工作量,从而 ...
- Linux磁盘分区(四)之分区大小调整
Linux磁盘分区(四)之分区大小调整在学习调整分区大小之前,先了解linx分区的概念.参考如下博客:[1]linux 分区 物理卷 逻辑卷 https://www.cnblogs.com/liuch ...
- Output of C++ Program | Set 1
Predict the output of below C++ programs. Question 1 1 // Assume that integers take 4 bytes. 2 #incl ...
- Linux:sqlldr命令
第一步:写一个 ctl格式的控制文件 CTL 控制文件的内容 : load data --1. 控制文件标识 infile 'xxx.txt' --2. 要导入的数据文件名 insert into t ...
- Servlet(2):通过servletContext对象实现数据共享
一,ServletContext介绍 web容器在启动时,它会为每一个web应用程序都创建一个ServletContext对象,它代表当前web应用 多个Servlet通过ServletContext ...
- contrller层的编码设设计流程以及详细配置
/** 实际开发中遵循一个规律:自己写的类使用注解,系统提供的类使用配置文件 1.书写controller类----->配置springmvc.xml-------->配置web ...
- Socket通信和多线程的总结
1.ServerSocket进行多线程接收 package com.yh.chat; import java.io.IOException; import java.net.ServerSocket; ...