Codeforces Round #200 (Div. 1) D - Water Tree 很经典而且很有趣的树 上dfs问题
来源:互联网 发布:ubuntu登陆后桌面假死 编辑:程序博客网 时间:2024/05/15 09:01
这道题疯狂wa了一大波,因为自己的线段树水平不够,更新 和 区间的理解还是大大的不够,所以一定要去多多学习。
题意:
给一颗树,有多次操作,有三种操作: 1. 把节点v 的所有 儿子节点(子树下的所有点)都充满水,2把节点v 的所有父亲节点的水都抽调。3.询问某个节点里面是否有水
.
一开始很年轻
感觉上 先跑出 dfs序,然后线段树维护一下节点flag值 就行了
好像感觉并不对,仔细想了想,如果我要把一个区间为: 2-4 这个节点 x清空,那么意味着x 有两个子节点1(3.3) 和2(4.4) 但是我不能把 1和2 清空啊。‘
那么我们在更新的时候修改一下姿势,和更新姿势没有关系,哪一种都是那样更新的
我们up 节点x的时候可以 吧区间弄为 L[x],L[x] ,这样就只会改变x 的祖先节点的flag值。
但是询问结果我们发现还是无法询问,因为区间不可能有两个啊,
那我们只能建两棵树了, 干脆区别对待
对于每一次的询问,我们都在两棵树上对同一个节点进行询问,看最后一次更新是1,还是2,由此便可得到是否有水
!!!!!!!仔细看看 线段树的更新 和询问 ,区间是很值得研究的 !!!!!!!
代码贴别人的,自己写的太丑了,就不拿出来了,蛤蛤
#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<stdlib.h>#include<queue>#include<stack>#include<map>#include<vector>#define mem(a) memset(a,0,sizeof(a))#define INF 0x7fffffff //INT_MAX#define inf 0x3f3f3f3f //const double PI = acos(-1.0);const double e = exp(1.0);template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }bool cmpbig(int a,int b){return a>b;}bool cmpsmall(int a,int b){return a<b;}using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")const int N=500005;using namespace std;vector<int> E[N];int i, j, k, l, x, type, y, dfn[N], dfn2[N], tim, n, m;struct seg_tree { int s[N * 4], sign[N * 4]; void cover(int p, int l, int r, int x, int y, int k) { if (x <= l && y >= r) { s[p] = sign[p] = k;// printf("i=%d p=%d s=%d\n",i,p,s[p]); return; } int mid = l + r >> 1; if (x <= mid) cover(p << 1, l, mid, x, y, k); if (y > mid) cover((p << 1) + 1, mid + 1, r, x, y, k); s[p] = max(s[p << 1], s[(p << 1) + 1]);// printf("i=%d p=%d s=%d\n",i,p,s[p]); } int calc(int p, int l, int r, int x, int y) { if (x <= l && y >= r) return s[p]; int mid = l + r >> 1, res = 0; if (x <= mid) res = max(res, calc(p << 1, l, mid, x, y)); if (y > mid) res = max(res, calc((p << 1) + 1, mid + 1, r, x, y)); return max(sign[p], res); }} T1, T2;void dfs(int x, int ff) { dfn[x] = ++tim; for (int i = E[x].size() - 1; i >= 0; --i) if (E[x][i] != ff) dfs(E[x][i], x); dfn2[x] = tim;}int main() { scanf("%d", &n); for (i = 1; i < n; ++i) { scanf("%d%d", &x, &y); E[x].push_back(y); E[y].push_back(x); } dfs(1, 0); scanf("%d", &m); for (i = 1; i <= m; ++i) { scanf("%d%d", &type, &x); if (type == 1) { T1.cover(1, 1, n, dfn[x], dfn2[x], i); } if (type == 2) { T2.cover(1, 1, n, dfn[x], dfn[x], i); } if (type == 3) { int v1 = T1.calc(1, 1, n, dfn[x], dfn[x]); int v2 = T2.calc(1, 1, n, dfn[x], dfn2[x]);// printf("v= %d %d\n",v1,v2); if (v2 >= v1) puts("0"); else puts("1"); } }}
0 0
- Codeforces Round #200 (Div. 1) D - Water Tree 很经典而且很有趣的树 上dfs问题
- Codeforces Round #200 (Div. 1)D. Water Tree 【dfs序+线段树】
- Codeforces Round #200 (Div. 1) D. Water Tree(dfs序+线段树)
- 【Codeforces Round #200 (Div. 1)】Codeforces 343D Water Tree
- Codeforces Round #200 (Div. 1)D Water Tree
- Codeforces Round #200 (Div. 1) D. Water Tree
- Codeforces Round #200 (Div. 1) D.Water Tree
- Codeforces Round #200 (Div. 1) Water Tree (dfs序+线段树)
- Codeforces Round 200 Div1 D Water Tree (树上线段树)
- Codeforces Round #316 (Div. 2) D. Tree Requests (DFS序)
- 有趣的线段树小集合 Codeforces Round #250 (Div. 1) D. The Child and Sequence
- [树的直径] Codeforces 804D Round #411 (Div. 1) D. Expected diameter of a tree
- Codeforces 343D Water Tree dfs序+线段树
- 【Codeforces 343D】Water Tree dfs序建树+线段树
- [dfs序+线段树] codeforces 343D. Water Tree
- codeforces #343d water tree(dfs+线段树)
- CodeForces 343D Water Tree(dfs序 线段树)
- Codeforces Round #411 (Div. 1) D. Expected diameter of a tree(树的直径)
- Geekband C++面向对象高级编程(上) 第三周笔记 暗影行者
- 理解Java中HashMap的工作原理
- "巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场(重现) HDU 5704
- IEEE 802.15.4协议完整中文版 - 目录
- Ubuntu默认root用户密码
- Codeforces Round #200 (Div. 1) D - Water Tree 很经典而且很有趣的树 上dfs问题
- spring、springmvc、mybatis整合(SSM)
- spring mvc中的登录拦截器java类中,重写的三个方法是什么意思()
- html5本地存储localStorage 存储json对象存储格式问题
- 《java入门第一季》之Socket编程通信和TCP协议通信图解
- Ubuntun
- 第16课:Spark streaming 源码解读之数据清理内幕彻底揭秘
- M3数据库的压缩程序设计M3 Eob Database Compacted
- 实习第八天:SurfaceView显示动画效果(1)