题意:给你一颗以点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 线段树的更多相关文章

  1. CodeForces 343D 线段树维护dfs序

    给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...

  2. Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论

    Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...

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

  4. Codeforces 938G 线段树分治 线性基 可撤销并查集

    Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...

  5. codeforces 1136E 线段树

    codeforces 1136E: 题意:给你一个长度为n的序列a和长度为n-1的序列k,序列a在任何时候都满足如下性质,a[i+1]>=ai+ki,如果更新后a[i+1]<ai+ki了, ...

  6. Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset

    Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...

  7. D - The Bakery CodeForces - 834D 线段树优化dp···

    D - The Bakery CodeForces - 834D 这个题目好难啊,我理解了好久,都没有怎么理解好, 这种线段树优化dp,感觉还是很难的. 直接说思路吧,说不清楚就看代码吧. 这个题目转 ...

  8. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路

    B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...

  9. Linear Kingdom Races CodeForces - 115E (线段树优化dp)

    大意: n条赛道, 初始全坏, 修复第$i$条花费$a_i$, m场比赛, 第$i$场比赛需要占用$[l_i,r_i]$的所有赛道, 收益为$w_i$, 求一个比赛方案使得收益最大. 设$dp[i]$ ...

随机推荐

  1. setclock - 用系统时间来设置硬件时间

    总览 setclock 描述 setclock 用当前系统时钟存储的时间设置系统的硬件时间. 它先读取 /etc/sysconfig/clock 的时间格式, 时间存储前应该转化成这种格式. Red ...

  2. linux---postgresql的安装和配置

    postgresql的安装:源码安装(推荐):http://my.oschina.net/hippora/blog/375292 1.tar -xjvf postgresql-9.3.4.tar.bz ...

  3. Codeforces 1188A 构造

    题意:给你一颗树,树的边权都是偶数,并且边权各不相同.你可以选择树的两个叶子结点,并且把两个叶子结点之间的路径加上一个值(可以为负数),问是否可以通过这种操作构造出这颗树?如果可以,输出构造方案.初始 ...

  4. mybatis 自定义查询语句

    通过mybatis插件生成的mapper文件只有基本的增.删.改.查.汇总.但是实际使用场景中,总是有各种需要连表.汇总.分组查询的需求,那我们一般都通过自定义查询语句去实现. 有时候会有表结构更改的 ...

  5. spring Data solr依赖文件 和xml配置文件

    <dependencies>        <dependency>            <groupId>org.springframework.data< ...

  6. PHP FILTER_SANITIZE_STRING 过滤器

    定义和用法 FILTER_SANITIZE_STRING 过滤器去除或编码不需要的字符. 该过滤器删除那些对应用程序有潜在危害的数据.它用于去除标签以及删除或编码不需要的字符. Name: " ...

  7. Qt installer framework学习

    一.官网的介绍部分网址 http://doc.qt.io/qtinstallerframework/ifw-overview.html 二.安装界面介绍 2.1 安装界面流程 介绍>>选择 ...

  8. php-fpm.conf详细解析篇

    一:php-fpm.conf详细解析篇: pm = static (静态模式)时只需修改 max_children数值 pm = dynamic (动态模式)时只需修改其它三个数值 pm.max_ch ...

  9. wrtnode板

    Arduino技术交流:www.openjumper.com QQ群 ArduinoCN I  : 180646674,ArduinoCN II : 203870250 商品详情 产品介绍 : WRT ...

  10. js类型问题

    js比较数据一定要记得鉴别类型是否一致,number类型转换string 需要用到toString方法