【诚邀】求大佬帮蒟蒻看看树剖怎么挂了
查看原帖
【诚邀】求大佬帮蒟蒻看看树剖怎么挂了
452407
TSTYFST楼主2022/7/30 20:43

rt

#include<cstdio>
#include<algorithm>

using namespace std;

const int MAXN = 1e5 + 10;
int n, q, cnt, num;
int head[MAXN], rel[MAXN], val[MAXN];
int fa[MAXN], size[MAXN], deep[MAXN];
int dfn[MAXN], son[MAXN], top[MAXN];

struct Edge{
    int to, next;
}e[MAXN << 1];

inline void Add(int u, int v){
    e[++cnt].to = v;
    e[cnt].next = head[u];
    head[u] = cnt;
}

struct Segment_Tree{
    int tot;
    int root[MAXN];

    struct Tree{
        int lson, rson;
        int max, sum;

        Tree(){
            lson = rson = 0;
            max = sum = 0;
        }
    }tr[MAXN * 25];

    Segment_Tree(){
        tot = 0;
    }

    #define lson(x) tr[x].lson
    #define rson(x) tr[x].rson

    inline void Pushup(int rt){
        tr[rt].sum = tr[lson(rt)].sum + tr[rson(rt)].sum;
        tr[rt].max = max(tr[lson(rt)].max, tr[rson(rt)].max);
    }

    void Update(int &rt, int pos, int data, int L, int R){
        if(!rt) rt = ++tot;

        if(L == R){
            tr[rt].sum = data;
            tr[rt].max = data;
            return;
        }

        int mid = (L + R) >> 1;
        if(pos <= mid) Update(lson(rt), pos, data, L, mid);
        else Update(rson(rt), pos, data, mid + 1, R);

        Pushup(rt);
    }

    void Delete(int rt, int pos, int L, int R){
        if(!rt) return;

        if(L == R){
            tr[rt].sum = 0;
            tr[rt].max = 0;
            return;
        }

        int mid = (L + R) >> 1;
        if(pos <= mid) Delete(lson(rt), pos, L, mid);
        else Delete(rson(rt), pos, mid + 1, R);

        Pushup(rt);
    }

    int Query_Sum(int rt, int l, int r, int L, int R){
        if(!rt) return 0;

        if(l <= L && r >= R)
            return tr[rt].sum;

        int mid = (L + R) >> 1;
        if(r <= mid) return Query_Sum(lson(rt), l, r, L, mid);
        else if(l > mid) return Query_Sum(rson(rt), l, r, mid + 1, R);
        else return Query_Sum(lson(rt), l, r, L, mid) + Query_Sum(rson(rt), l, r, mid + 1, R);
    }

    int Query_Max(int rt, int l, int r, int L, int R){
        if(!rt) return 0;

        if(l <= L && r >= R)
            return tr[rt].max;
        
        int mid = (L + R) >> 1;
        if(r <= mid) return Query_Max(lson(rt), l, r, L, mid);
        else if(l > mid) return Query_Max(rson(rt), l, r, mid + 1, R);
        else return max(Query_Max(lson(rt), l, r, L, mid), Query_Max(rson(rt), l, r, mid + 1, R));
    }
}S;

void dfs_deep(int rt, int father, int depth){
    size[rt] = 1;
    fa[rt] = father;
    deep[rt] = depth;

    int max_son = -1;
    for(register int i = head[rt]; i; i = e[i].next){
        int v = e[i].to;
        if(v == father) continue;

        dfs_deep(v, rt, depth + 1);
        size[rt] += size[v];

        if(size[v] > max_son){
            son[rt] = v;
            max_son = size[v];
        }
    }
}

void dfs_top(int rt, int top_fa){
    dfn[rt] = ++num;
    top[rt] = top_fa;

    if(!son[rt]) return;
    dfs_top(son[rt], top_fa);

    for(register int i = head[rt]; i; i = e[i].next){
        int v = e[i].to;

        if(!dfn[v]) dfs_top(v, v);
    }
}

int Query_Sum_Tree(int x, int y, int opt){
    int ans = 0;

    while(top[x] != top[y]){
        if(deep[top[x]] < deep[top[y]]) swap(x, y);
        ans += S.Query_Sum(S.root[opt], dfn[top[x]], dfn[x], 1, n);
        x = fa[top[x]];
    }

    if(deep[x] > deep[y]) swap(x, y);
    ans += S.Query_Sum(S.root[opt], dfn[x], dfn[y], 1, n);

    return ans;
}

int Query_Max_Tree(int x, int y, int opt){
    int ans = -1;

    while(top[x] != top[y]){
        if(deep[top[x]] < deep[top[y]]) swap(x, y);
        ans+= max(ans, S.Query_Max(S.root[opt], dfn[top[x]], dfn[x], 1, n));
        x = fa[top[x]];
    }

    if(deep[x] > deep[y]) swap(x, y);
    ans = max(ans, S.Query_Max(S.root[opt], dfn[x], dfn[y], 1, n));

    return ans;
}

inline int read(){
    int x = 0, f = 1;
    char c = getchar();

    while(c < '0' || c > '9'){
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9'){
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * f;
}

int main(){
    n = read(), q = read();
    for(register int i = 1; i <= n; i++){
        val[i] = read();
        rel[i] = read();
    }
    for(register int i = 1; i <= n - 1; i++){
        int u, v;
        u = read(), v = read();
        Add(u, v);
        Add(v, u);
    }

    dfs_deep(1, 0, 1);
    dfs_top(1, 1);    
    for(register int i = 1; i <= n; i++)
        S.Update(S.root[rel[i]], dfn[i], val[i], 1, n);

    for(register int i = 1; i <= q; i++){
        char opt[5];
        scanf("%s", opt + 1);

        if(opt[1] == 'C' && opt[2] == 'C'){
            int x, c;
            x = read(), c = read();

            S.Delete(S.root[rel[x]], dfn[x], 1, n);
            rel[x] = c;
            S.Update(S.root[rel[x]], dfn[x], val[i], 1, n);
        }
        else if(opt[1] == 'C' && opt[2] == 'W'){
            int x, w;
            x = read(), w = read();

            val[x] = w;
            S.Update(S.root[rel[x]], dfn[x], w, 1, n);
        }
        else if(opt[1] == 'Q' && opt[2] == 'S'){
            int x, y;
            x = read(), y = read();

            printf("%d\n", Query_Sum_Tree(x, y, rel[x]));
        }
        else if(opt[1] == 'Q' && opt[2] == 'M'){
            int x, y;
            x = read(), y = read();

            printf("%d\n", Query_Max_Tree(x, y, rel[x]));
        }
    } 

    return 0;
}
2022/7/30 20:43
加载中...