CodeForces 343D Water Tree(dfs序 线段树)

xiaoxiao2021-02-28  74

题意:给你一颗n个节点的树,1为根,初始时所有节点都为0,有三种操作:

1 x :将x及其子树的所有节点都变为1

2 x :将x及其祖先都变为0

3 x :查询x的值

思路:可以先求出dfs序,对于操作1,我们可以用线段树区间更新in[x]至out[x];对于操作2,需要更新它及其祖先,

太好操作,我们可以只将x变为0,这样对于操作3,我们可以查找其子树最小值,如果是0就代表它也会变为0,否

则就是1。这样一来操作1可能会把操作2的0给覆盖掉,所以在进行操作1时要把其父节点变为0。

代码:

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 5e5+5; int tree[maxn*4], lazy[maxn*4], in[maxn*4], out[maxn*4], fa[maxn*4], tot; vector<int> g[maxn]; void dfs(int u, int pre) { in[u] = ++tot; fa[u] = pre; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if(v != pre) dfs(v, u); } out[u] = tot; } void push_up(int root) { tree[root] = min(tree[root*2], tree[root*2+1]); } void push_down(int root) { if(lazy[root] != -1) { tree[root*2] = tree[root*2+1] = lazy[root]; lazy[root*2] = lazy[root*2+1] = lazy[root]; lazy[root] = -1; } } void update(int root, int l, int r, int i, int j, int op) { if(i <= l && j >= r) { tree[root] = lazy[root] = op; return ; } push_down(root); int mid = (l+r)/2; if(i <= mid) update(root*2, l, mid, i, j, op); if(j > mid) update(root*2+1, mid+1, r, i, j, op); push_up(root); } int query(int root, int l, int r, int i, int j) { if(i <= l && j >= r) return tree[root]; push_down(root); int mid = (l+r)/2; if(j <= mid) return query(root*2, l, mid, i, j); else if(i > mid) return query(root*2+1, mid+1, r, i, j); else return min(query(root*2, l, mid, i, j), query(root*2+1, mid+1, r, i, j)); } int main(void) { int n; while(cin >> n) { tot = 0; memset(tree, 0, sizeof(tree)); memset(lazy, -1, sizeof(lazy)); for(int i = 0; i <= n; i++) g[i].clear(); for(int i = 0; i < n-1; i++) { int u, v; scanf("%d%d", &u, &v); g[u].push_back(v); g[v].push_back(u); } dfs(1, 0); int q; scanf("%d", &q); while(q--) { int cmd, x; scanf("%d%d", &cmd, &x); if(cmd == 1) { int tmp = query(1, 1, tot, in[x], out[x]); update(1, 1, tot, in[x], out[x], 1); if(!tmp && fa[x]) update(1, 1, tot, in[fa[x]], in[fa[x]], 0); } else if(cmd == 2) update(1, 1, tot, in[x], in[x], 0); else printf("%d\n", query(1, 1, tot, in[x], out[x])); } } return 0; }

转载请注明原文地址: https://www.6miu.com/read-69272.html

最新回复(0)