CF343D Water Tree

CF343D Water Tree

写珂朵莉树也就图一乐呵,要真冲还是要写线段树

题目给你一颗有根树,一个操作是将一个子树状态推平,另一个是将一个点到根的路径推平。

第一个操作直接区间覆盖\([dfn[u],dfn[u] + size[u] - 1]\)即可。

第二个操作按重链一直跳上去,遇到连续的就区间覆盖即可。

区间覆盖当然可以用到珂朵莉树啦!但是这道题数据不随机,况且std::set常数太大了。

结果只能写个线段树。不嗨森

#include<bits/stdc++.h>
 
const int maxn = 500005;
int n, q;
std::vector<int> G[maxn];
 
int size[maxn], wson[maxn], fa[maxn], dep[maxn];
int top[maxn], dfn[maxn], pre[maxn], dtot;
 
void dfs1(int u, int f) {
    dep[u] = dep[f] + 1; size[u] = 1; fa[u] = f;
    for(auto v: G[u]) {
        if(v == f) continue;
        dfs1(v, u);
        size[u] += size[v];
        if(size[v] > size[wson[u]]) wson[u] = v;
    }
}
void dfs2(int u, int topf) {
    dfn[u] = ++dtot; pre[dtot] = u; top[u] = topf;
    if(wson[u]) dfs2(wson[u], topf);
    for(auto v: G[u]) {
        if(v == fa[u] || v == wson[u]) continue;
        dfs2(v, v);
    }
}
 
struct segTree {
    int val[maxn << 2], lazy[maxn << 2];
    #define lson (root << 1)
    #define rson (root << 1 | 1)
    void pushdown(int root) {
        if(lazy[root]) {
            val[lson] = val[rson] = val[root];
            lazy[lson] = lazy[rson] = 1; lazy[root] = 0;
        }
    }
    void update(int root, int l, int r, int x, int y, int k) {
        if(r < x || y < l) return;
        if(x <= l && r <= y) {
            val[root] = k; lazy[root] = 1;
            return;
        }
        pushdown(root);
        int mid = (l + r) >> 1;
        update(lson, l, mid, x, y, k);
        update(rson, mid + 1, r, x, y, k);
    }
    int query(int root, int l, int r, int pos) {
        if(l == r) return val[root];
        pushdown(root);
        int mid = (l + r) >> 1;
        if(pos <= mid) return query(lson, l, mid, pos);
        else return query(rson, mid + 1, r, pos);
    }
} seg;
 
int read() {
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0') {
        if(ch == '-') s = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        ans = ans * 10 + ch - '0';
        ch = getchar();
    }
    return s * ans;
}
int main() {
    n = read();
    for(int i = 1; i < n; i++) {
        int u = read(), v = read();
        G[u].push_back(v); G[v].push_back(u);
    }
    dfs1(1, 0); dfs2(1, 1);
    q = read();
    while(q--) {
        int opt = read(), u = read();
        if(opt == 1) {
            seg.update(1, 1, n, dfn[u], dfn[u] + size[u] - 1, 1);
        } else if(opt == 2) {
            while(top[u] != 1) {
                seg.update(1, 1, n, dfn[top[u]], dfn[u], 0);
                u = fa[top[u]];
            }
            seg.update(1, 1, n, dfn[1], dfn[u], 0);
        } else if(opt == 3) {
            printf("%d\n", seg.query(1, 1, n, dfn[u]));
        }
        //print();
    }
}
posted @ 2019-07-30 22:44  Garen-Wang  阅读(194)  评论(0编辑  收藏  举报