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]$ ...
随机推荐
- MQ总结
对于ActiveMQ:JMS可靠消息机制.JMS发布订阅与点对点通讯.ActiveMQ高可用集群解决方案.ActiveMQ补偿与重试策略.ActiveMQ整合SpringBoot Kafka:整合Zo ...
- bzoj 2364
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2346 比较裸的最短路(' ' ) 水题又多了一道 #include <iost ...
- nucleus plus学习总结(后续)
前言: 刚刚抽筋点了保存发布,结果要审核,那就分开写个续好了. 内容: signal 信号是异步通知task的一种机制,HISR是不可以接收信号的,但是可以发送信号. TCB中 ...
- centos6编译安装php7
https://www.cnblogs.com/wenwei-blog/p/6261637.html https://www.cnblogs.com/imzye/p/5109770.html cent ...
- 【Java架构:基础技术】一篇文章搞掂:MyBatis-Plus
前言 Mybatis:一个流行的半自动ORM框架. Mybatis-Plus:一个Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发.提高效率而生. 本文使用的版本:myb ...
- 有关JWT(Json Web Token)的那些事
用户认证是计算机安全领域一个永恒的热点话题,然而你会发现,开发者很少讨论有关Json Web Token的话题,其实使用Json Web Token集成到API身份验证机制中是容易,本文给大家普及基础 ...
- 93、R语言教程详解
加载数据 > w<-read.table("test.prn",header = T) > w X.. X...1 1 A 2 2 B 3 3 C 5 4 D 5 ...
- kruskal算法【最小生成树2】
设G=(V,E)是无向连通带权图,V={1,2,…,n}: 设最小生成树T=(V,TE),该树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),Kruskal算法将这n个顶点看成是n个孤立的连 ...
- 使用mybatis进行一对多嵌套查询时出错:输出结果:Country{id=2, name='美国', minister=[null]}
即Minister类作为Country类的关联属性. 查询的输出结果是:Country{id=2, name='美国', minister=[null]} <!--mapper.xml内容--& ...
- 第一周复习二 (CSS样式表及其属性)
样式表三种写法 1内联写法:style直接写在标签内.个人感觉多用于个别标签,一般情况优先级较高 style="font-size:16px;" 2内嵌写法:写在<head& ...