题意:给你一颗以点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. Mac 安装cnpm

    1.先安装node   node的下载地址:http://nodejs.cn/download/   这个没什么好说的,安装完成后测试一下,在终端输入:node -v   这时候就可以看到安装的nod ...

  2. Nhibernet Get方法获取数据后,修改字段,未保存,但是数据库的数据却同步了

    首先,对象是在session中取得的,所以这个对象已经和数据库同步了,或者说相关联了如果你的session中的对象发生变法,提交事务后,数据库中的数据也会更新未保存更改,不要以为session就不会在 ...

  3. 第十三章 存储之volume

    容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题.首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动.其 ...

  4. Quartz.Net 任务调度之传递参数(2)

    1.jobDetail //添加 //Key:Value jobDetail.JobDataMap.Add("张翼德", "张翼德"); jobDetail.J ...

  5. cocos2D-X c++ call java

    { //https://blog.csdn.net/yuechuzhao/article/details/9283847 }

  6. Spring data jpa 依赖配置

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...

  7. 【LeetCode 37】解数独

    题目链接 [题解] 回溯法搞一下. 用set和数组下标判重. [代码] class Solution { public: set<int> myset[9]; int hang[9][10 ...

  8. fedora下手动编译安装vim

    据说手动编译安装可以更适合自己的电脑哦- 1.首先,我门要下载源文件,下载地址:ftp://ftp.vim.org/pub/vim/unix/ 选择一个最新版本,我这里选择的是 vim-7.4.tar ...

  9. Hadoop2.7.3+Hbase-1.2.6+spark2.1.2完全分布式安装部署

    https://www.cnblogs.com/lzxlfly/p/7221890.html 总的下载地址:      http://mirror.bit.edu.cn/apache/ hadoop下 ...

  10. Brute Force(暴力(破解))

    一.攻击模块1:Brute Force(暴力破解) 暴力破解一般指穷举法,穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕.若某个情况 ...