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]$ ...
随机推荐
- setclock - 用系统时间来设置硬件时间
总览 setclock 描述 setclock 用当前系统时钟存储的时间设置系统的硬件时间. 它先读取 /etc/sysconfig/clock 的时间格式, 时间存储前应该转化成这种格式. Red ...
- linux---postgresql的安装和配置
postgresql的安装:源码安装(推荐):http://my.oschina.net/hippora/blog/375292 1.tar -xjvf postgresql-9.3.4.tar.bz ...
- Codeforces 1188A 构造
题意:给你一颗树,树的边权都是偶数,并且边权各不相同.你可以选择树的两个叶子结点,并且把两个叶子结点之间的路径加上一个值(可以为负数),问是否可以通过这种操作构造出这颗树?如果可以,输出构造方案.初始 ...
- mybatis 自定义查询语句
通过mybatis插件生成的mapper文件只有基本的增.删.改.查.汇总.但是实际使用场景中,总是有各种需要连表.汇总.分组查询的需求,那我们一般都通过自定义查询语句去实现. 有时候会有表结构更改的 ...
- spring Data solr依赖文件 和xml配置文件
<dependencies> <dependency> <groupId>org.springframework.data< ...
- PHP FILTER_SANITIZE_STRING 过滤器
定义和用法 FILTER_SANITIZE_STRING 过滤器去除或编码不需要的字符. 该过滤器删除那些对应用程序有潜在危害的数据.它用于去除标签以及删除或编码不需要的字符. Name: " ...
- Qt installer framework学习
一.官网的介绍部分网址 http://doc.qt.io/qtinstallerframework/ifw-overview.html 二.安装界面介绍 2.1 安装界面流程 介绍>>选择 ...
- php-fpm.conf详细解析篇
一:php-fpm.conf详细解析篇: pm = static (静态模式)时只需修改 max_children数值 pm = dynamic (动态模式)时只需修改其它三个数值 pm.max_ch ...
- wrtnode板
Arduino技术交流:www.openjumper.com QQ群 ArduinoCN I : 180646674,ArduinoCN II : 203870250 商品详情 产品介绍 : WRT ...
- js类型问题
js比较数据一定要记得鉴别类型是否一致,number类型转换string 需要用到toString方法