zoukankan      html  css  js  c++  java
  • CF343D Water Tree(水树?)

    题面

    思路:树剖+线段树。

    树剖的裸题。

    线段树维护时标记下放的过程中,有个小细节需要注意:在父亲节点的标记下放完成后,标记为(-1),因为如果置为(0),那么在下次操作时会把(0)当做你的操作下放下去....啊可能也有别的处理方法,反正我是这么处理的qwq。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    template<typename temp>void read(temp &x){
        x = 0;temp f = 1;char ch;
        while(!isdigit(ch = getchar())) (ch == '-') and (f = -1);
        for(x = ch^48; isdigit(ch = getchar()); x = (x<<1)+(x<<3)+(ch^48));
        x *= f;
    }
    template <typename temp, typename ...Args>void read(temp& a, Args& ...args){read(a), read(args...);}
    
    const int maxn = 1e6;
    
    int n, m, ans;
    
    vector<int> v[maxn];
    
    struct poutree{
        #define ls (now<<1)
        #define rs (now<<1|1)
        #define mid ((l+r)>>1)
        int cnt, dfn[maxn], low[maxn], height_son[maxn], size[maxn], top[maxn], fa[maxn], dep[maxn];
        struct no{
            int l, r, tag;
        }node[maxn<<1];
        void build_poutree(int now){
            size[now] = 1;
            for(int i = 0; i < v[now].size(); i ++){
                int to = v[now][i];
                if(dep[to]) continue;
                dep[to] = dep[fa[to]=now] + 1;
                build_poutree(to);
                size[now] += size[to];
                if(size[to] > size[height_son[now]]) height_son[now] = to;
            }
        }
        void dfs(int now, int topfa){
            top[now] = topfa, dfn[now] = ++cnt;
            if(height_son[now]) dfs(height_son[now],topfa);
            for(int i = 0; i < v[now].size(); i ++){
                int to = v[now][i];
                if(fa[now] == to or height_son[now] == to) continue;
                dfs(to,to);
            }
        }
        void down(int now){
            if(node[now].tag == -1) return;
            node[ls].tag = node[rs].tag = node[now].tag;
            node[now].tag = -1;
        }
        void build_segtree(int l, int r, int now){
            node[now].l = l, node[now].r = r;
            if(l == r) return(void)(node[now].tag = 0);
            build_segtree(l, mid, ls), build_segtree(mid+1, r, rs);
            return;
        }
        void chenge(int l, int r, int now, int val){
            if(node[now].l > r or node[now].r < l) return;
            if(l <= node[now].l and node[now].r <= r) return(void)(node[now].tag = val);
            down(now);
            chenge(l, r, ls, val), chenge(l, r, rs, val);
            return;
        }
        void quary(int l, int r, int now, int &val){
            if(node[now].l > r or node[now].r < l) return;
            if(l <= node[now].l and node[now].r <= r) return(void)(val += node[now].tag);
            down(now);
            quary(l, r, ls, val), quary(l, r, rs, val);
            return;
        }
        void function(int opt, int x){
            if(opt == 1) chenge(dfn[x], dfn[x]+size[x]-1, 1, 1);
            if(opt == 2) while(x) chenge(dfn[top[x]], dfn[x], 1, 0), x = fa[top[x]];
            if(opt == 3) quary(dfn[x], dfn[x], 1, ans=0), printf("%d
    ", ans);
        }
    }tree;
    
    signed main(){
        read(n);
        for(int i = 1, x, y; i < n; i ++){
            read(x, y);
            v[x].push_back(y), v[y].push_back(x);
        }
        tree.build_poutree(1*(tree.dep[1]=1)), tree.dfs(1,1), tree.build_segtree(1,n,1);
        read(m);
        for(int opt, x; m; m --){
            read(opt, x);
            tree.function(opt, x);
        }
        return 0;
    }
    
  • 相关阅读:
    【NOI2008】志愿者招募
    【2010国家集训队】人员雇佣
    html5手机移动端三级联动城市选择器
    WebSocket实现简单的在线聊天
    游戏开发完整学习路线(各个版本都有)
    vs下开发windows服务程序
    解决Firefox下,页面元素不刷新问题
    C# JObject和JArray 的分享
    jQuery如何改变css伪元素样式
    safari 浏览器window.history.go(-1)运行无效解决办法
  • 原文地址:https://www.cnblogs.com/Vanyun/p/13399760.html
Copyright © 2011-2022 走看看