zoukankan      html  css  js  c++  java
  • [HAOI2015]树上操作

    https://www.luogu.org/recordnew/show/5120068

    long long

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int N = 1e5 + 10;
    
    #define gc getchar()
    #define lson jd << 1
    #define rson jd << 1 | 1
    #define LL long long
    
    LL ans;
    LL n, Ti, tim_clock, now = 1;
    LL head[N], tree[N], bef[N << 2], deep[N], data[N], fa[N], topp[N], siz[N], son[N], L[N], R[N];
    struct Node{
        LL u, v, nxt;
    }G[N << 2];
    struct Node_2{
        LL l, r;
        LL w, f;
    }T[N << 4];
    
    inline LL read(){
        LL x = 0, f = 1; char c = gc;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc;}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x * f;
    }
    
    inline void add(LL u, LL v){
        G[now].v = v; G[now].nxt = head[u]; head[u] = now ++;
    }
    
    void dfs_find_son(LL u, LL f, LL dep){
        fa[u] = f; deep[u] = dep;
        siz[u] = 1;
        for(LL i = head[u]; ~ i; i = G[i].nxt){
            LL v = G[i].v;
            if(v != f) {
                dfs_find_son(v, u, dep + 1);
                siz[u] += siz[v];
                if(siz[v] > siz[son[u]]) son[u] = v;
            }
        }
    }
    
    void dfs_to_un(LL u, LL tp){
        topp[u] = tp;
        L[u] = ++ tim_clock;
        tree[u] = tim_clock;
        bef[tim_clock] = u;
        if(!son[u]){R[u] = tim_clock; return ;}
        dfs_to_un(son[u], tp);
        for(LL i = head[u]; ~ i; i = G[i].nxt){
            LL v = G[i].v;
            if(v != fa[u] && v != son[u]) dfs_to_un(v, v);
        }
        R[u] = tim_clock;
    }
    
    void down(LL jd){
        LL F = T[jd].f;
        T[lson].w += ((T[lson].r - T[lson].l + 1) * F); T[lson].f += F;
        T[rson].w += ((T[rson].r - T[rson].l + 1) * F); T[rson].f += F;
        T[jd].f = 0;
    }
    
    void build_tree(LL l, LL r, LL jd){
        T[jd].l = l; T[jd].r = r;
        if(l == r){T[jd].w = data[bef[l]]; return ;}
        LL mid = (l + r) >> 1;
        build_tree(l, mid, lson);
        build_tree(mid + 1, r, rson);
        T[jd].w = T[lson].w + T[rson].w;
    }
    
    void Poi_G(LL l, LL r, LL jd, LL x, LL yj){
        if(l == r) {T[jd].w += yj; return ;}
        if(T[jd].f) down(jd);
        LL mid = (l + r) >> 1;
        if(x <= mid) Poi_G(l, mid, lson, x, yj);
        else Poi_G(mid + 1, r, rson, x, yj);
        T[jd].w = T[lson].w + T[rson].w;
    }
    
    void Sec_G(LL l, LL r, LL jd, LL x, LL y, LL yj){
        if(x <= l && r <= y) {T[jd].w += ((r - l + 1) * yj); T[jd].f += yj; return ;}
        if(T[jd].f) down(jd);
        LL mid = (l + r) >> 1;
        if(x <= mid) Sec_G(l, mid, lson, x, y, yj);
        if(y > mid)  Sec_G(mid + 1, r, rson, x, y, yj);
        T[jd].w = T[lson].w + T[rson].w;
    }
    
    void Sec_A(LL l, LL r, LL jd, LL x, LL y){
        if(x <= l && r <= y) {ans += T[jd].w; return ;}
        if(T[jd].f) down(jd);
        LL mid = (l + r) >> 1;
        if(x <= mid) Sec_A(l, mid, lson, x, y);
        if(y > mid)  Sec_A(mid + 1, r, rson, x ,y);
    }
    
    inline LL Sec_A_I(LL x, LL y){
        LL tp1 = topp[x], tp2 = topp[y]; LL answer = 0;
        while(tp1 != tp2){
            if(deep[tp1] < deep[tp2]) swap(x, y), swap(tp1, tp2);
            ans = 0;
            Sec_A(1, n, 1, tree[tp1], tree[x]);
            answer += ans;
            x = fa[tp1];
            tp1 = topp[x];
        }
        ans = 0;
        if(deep[x] < deep[y]) swap(x, y);
        Sec_A(1, n, 1, tree[y], tree[x]);
        answer += ans;
        return answer;
    }
    
    void debug(){
        for(LL i = 1; i <= n; i ++) cout << tree[i] << " ";
        cout << endl;
        exit(0);
    }
    
    int main()
    {
        n = read(); Ti = read();
        for(LL i = 1; i <= n; i ++) data[i] = read();
        for(LL i = 1; i <= n; i ++) head[i] = -1;
        for(LL i = 1; i < n ; i ++){
            LL u = read(), v = read();
            add(u, v); add(v, u);
        }
        
        dfs_find_son(1, 0, 1);
        dfs_to_un(1, 1);
        build_tree(1, n, 1);
        while(Ti --){
            LL how = read();
            if(how == 1){LL x = read(), a = read(); Poi_G(1, n, 1, tree[x], a);}
            else if(how == 2) {LL x = read(), a = read(); Sec_G(1, n, 1, L[x], R[x], a);}
            else {LL x = read(); printf("%lld
    ", Sec_A_I(x, 1));}
        }
        
        return 0;
    }
    /*
    5
    2 3 4 5
    2
    4
    3
    5
    3
    2 1
    5
    1 2
    3
    */
  • 相关阅读:
    element-ui日期筛选:选择日期即触发查询
    js点击按钮复制内容到粘贴板
    axios配置及使用(发起请求时带上token)
    axios + vue导出excel文件
    textarea与标签组合,点击标签填入标签内容,再次点击删除内容(vue)
    vue复制textarea文本域内容到粘贴板
    ElementUI动态表格数据转换formatter
    elementUI图片墙上传
    高德地图模糊搜索地址(elementUI)
    elementUI表单验证
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8098749.html
Copyright © 2011-2022 走看看