这道题疯狂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");
}
}
}