Codeforces 343D 线段树
题意:给你一颗以点1为根的数,有两种操作,一种是把x及其子树的所有点都灌满水,一种是把x及其所有祖先都放空水,一种是询问,问某个点里有没有水?
思路:看网上大多数是树剖,但实际上5e5的数据树剖还是有点慌的。。。我只用了线段树。我们发现,只要一个点被清空之后,如果没有灌水,那么这个点将一直是空的。同理,如果这个点被灌满水后一直不是空的,那么它将一直是满的,所以,这个点的状态实际取决于离查询时间最近的是放水还是灌水。我们可以用线段树来维护这个,我们首先来维护灌水时间,这个在dfs序后用线段树的区间操作,很好完成。那么放水呢?我们换个思维,清空这个点及其祖先,反过来说,如果这个点被清空了,那么一定是它的子树中的某个点被清空了,所以我们可以用线段树查询它被清空的最晚时间,与之前的操作比较,如果清空操作较晚,那么这个点就是空的,否则就是满的。
代码:
#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define db double
#define pii pair<int, int>
#define ls (x << 1)
#define rs ((x << 1) | 1)
using namespace std;
const int maxn = 500010;
int a[maxn];
int dfn[maxn], tot, sz[maxn];
vector<int> G[maxn];
struct node {
int add, del;
int lz;
};
node tr[maxn * 4];
void add(int x, int y) {
G[x].push_back(y);
G[y].push_back(x);
}
void pushup(int x) {
tr[x].del = max(tr[ls].del, tr[rs].del);
}
void maintain(int x, int y) {
tr[x].add = y;
tr[x].lz = y;
}
void pushdown(int x) {
if(tr[x].lz != -1) {
maintain(ls, tr[x].lz);
maintain(rs, tr[x].lz);
tr[x].lz = -1;
}
}
void build(int x, int l, int r) {
if(l == r) {
tr[x].lz = -1;
return;
}
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(x);
}
void add1(int x, int l, int r, int ql ,int qr, int val) {
if(l >= ql && r <= qr) {
maintain(x, val);
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if(ql <= mid) add1(ls, l, mid, ql, qr, val);
if(qr > mid) add1(rs, mid + 1, r, ql, qr, val);
pushup(x);
}
void add2(int x, int l, int r, int pos, int val) {
if(l == r) {
tr[x].del = val;
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if(pos <= mid) add2(ls, l, mid, pos, val);
else add2(rs, mid + 1, r, pos, val);
pushup(x);
}
int query1(int x, int l, int r, int pos) {
if(l == r) return tr[x].add;
pushdown(x);
int mid = (l + r) >> 1;
if(pos <= mid) return query1(ls, l, mid, pos);
else return query1(rs, mid + 1, r, pos);
}
int query2(int x, int l, int r, int ql, int qr) {
if(l >= ql && r <= qr) return tr[x].del;
pushdown(x);
int mid = (l + r) >> 1;
int ans = 0;
if(ql <= mid) ans = max(ans, query2(ls, l, mid, ql, qr));
if(qr > mid) ans = max(ans, query2(rs, mid + 1, r, ql, qr));
return ans;
}
void dfs(int x, int fa) {
dfn[x] = ++tot;
sz[x] = 1;
for (auto y : G[x]) {
if(y == fa) continue;
dfs(y, x);
sz[x] += sz[y];
}
}
int main() {
int n, m, x, y;
scanf("%d", &n);
for (int i = 1; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y);
}
dfs(1, -1);
build(1, 1, n);
scanf("%d", &m);
for(int i = 1; i <= m; i++) {
scanf("%d%d", &x, &y);
if(x == 1) {
add1(1, 1, n, dfn[y], dfn[y] + sz[y] - 1, i);
} else if(x == 2) {
add2(1, 1, n, dfn[y], i);
} else {
int tmp1 = query1(1, 1, n, dfn[y]), tmp2 = query2(1, 1, n, dfn[y], dfn[y] + sz[y] - 1);
if(tmp1 <= tmp2) printf("0\n");
else printf("1\n");
}
}
}
Codeforces 343D 线段树的更多相关文章
- CodeForces 343D 线段树维护dfs序
给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...
- Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论
Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组
Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this int ...
- Codeforces 938G 线段树分治 线性基 可撤销并查集
Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...
- codeforces 1136E 线段树
codeforces 1136E: 题意:给你一个长度为n的序列a和长度为n-1的序列k,序列a在任何时候都满足如下性质,a[i+1]>=ai+ki,如果更新后a[i+1]<ai+ki了, ...
- Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset
Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...
- D - The Bakery CodeForces - 834D 线段树优化dp···
D - The Bakery CodeForces - 834D 这个题目好难啊,我理解了好久,都没有怎么理解好, 这种线段树优化dp,感觉还是很难的. 直接说思路吧,说不清楚就看代码吧. 这个题目转 ...
- B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路
B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...
- Linear Kingdom Races CodeForces - 115E (线段树优化dp)
大意: n条赛道, 初始全坏, 修复第$i$条花费$a_i$, m场比赛, 第$i$场比赛需要占用$[l_i,r_i]$的所有赛道, 收益为$w_i$, 求一个比赛方案使得收益最大. 设$dp[i]$ ...
随机推荐
- hibernate 参数一览
实现包含了Hibernate与数据库的基本连接信息的配置方式有两种方式: 第一种是使用hibernate.properties文件作为配置文件. 第二种是使用hibernate.cfg.xml文件作为 ...
- 编译lineageos3
待更 上次尝试将小米开源的内核Xiaomi_Kernel_OpenSource升级到最新版本,花了几天时间解决lineageos编译报错 最后总算成功编译出镜像文件了 but twrp刷入镜像在启动界 ...
- Paint的Gradient的用法(转)
转自:https://www.jianshu.com/p/02b02c1696b2 Paint的Gradient的用法 嗯哼嗯哼嗯哼嗯哼 关注 2017.07.04 15:45* 字数 173 阅读 ...
- 虚拟机(JVM)如何加载类
首先JVM加载类的一般流程分三步: 加载 链接 初始化 那么是否全部Java类都是这样三步走的方式加载呢?我们可以从Java的数据类型去出发.Java分基本类型和引用类型.其中按照面向对象的特性,一切 ...
- Vue学习笔记【31】——Vue路由(computed计算属性的使用)
computed计算属性的使用 默认只有getter的计算属性: <div id="app"> <input type="text" ...
- testNG之异常测试
@Test(expectedExceptions = ) 在测试的时候,某些用例的输入条件,预期结果是代码抛出异常,那么这个时候就需要testNG的异常测试,先看一段会抛出异常的代码 exceptio ...
- PHP chgrp() 函数
定义和用法 chgrp() 函数改变指定文件的用户组. 如果成功则返回 TRUE,如果失败则返回 FALSE. 语法 chgrp(file,group) 参数 描述 file 必需.规定要检查的文件. ...
- python format函数的使用
转载自:http://www.cnblogs.com/kaituorensheng/p/5709970.html python自2.6后,新增了一种格式化字符串函数str.format(),威力十足, ...
- 公司-浪潮:浪潮/inspur
ylbtech-公司-浪潮:浪潮/inspur 浪潮集团有限公司,即浪潮集团,是中国本土综合实力强大的大型IT企业之一,中国领先的云计算.大数据服务商.浪潮集团旗下拥有浪潮信息.浪潮软件.浪潮国际.华 ...
- 网神SecVSS 3600漏洞扫描系统
网神SecVSS 3600漏洞扫描系统严格按照计算机信息系统安全的国家标准.相关行业标准设计.编写.制造.网神SecVSS 3600漏洞扫描系统可以对不同操作系统下的计算机(在可扫描IP范围内)进行漏 ...