树剖 WA 0pts,两个小时没de出来,求助大佬!!!
查看原帖
树剖 WA 0pts,两个小时没de出来,求助大佬!!!
826362
fanfanfan123楼主2023/7/2 19:03
#include <iostream>
#include <vector>
using namespace std;

#define se second
#define fi first
#define pb push_back

const int N = 100010;
typedef pair<int, int> PII;

struct edge{
    int v, w;
};

vector<edge> e[N];
PII edges[N];
int dep[N], fa[N], top[N], sz[N], idx, id[N], son[N];
int ww[N], nw[N];

struct node{
    int l, r, mx, add, ass;
}tr[N * 4];

void dfs1(int u, int f){
    dep[u] = dep[f] + 1, fa[u] = f, sz[u] = 1;
    for(auto &[v, w]: e[u]){
        if(v == f) continue;
        ww[v] = w;
        dfs1(v, u);
        sz[u] += sz[v];
        if(sz[son[u]] < sz[v]) son[u] = v;
    }
}

void dfs2(int u, int t){
    id[u] = ++ idx, nw[idx] = ww[u], top[u] = t;
    if(son[u]) dfs2(son[u], t);
    for(auto &[v, w]: e[u]){
        if(v == fa[u] || v == son[u]) continue;
        dfs2(v, v);
    }
}

void pushup(int u){
    tr[u].mx = max(tr[u << 1].mx, tr[u << 1 | 1].mx);
}

void pushdown(int u){
    int &add = tr[u].add, &ass = tr[u].ass;
    if(ass >= 0){
        tr[u << 1].mx = tr[u << 1 | 1].mx = ass;
        tr[u << 1].ass = tr[u << 1 | 1].ass = ass;
        tr[u << 1].add = tr[u << 1 | 1].add = 0;
        ass = -1, add = 0;
    }
    else if(add){
        tr[u << 1].mx += add, tr[u << 1 | 1].mx += add;
        tr[u << 1].add += add, tr[u << 1 | 1].add += add;
        add = 0;
    }
}

void build(int u, int l, int r){
    tr[u] = {l, r, nw[l], 0, -1};
    if(l == r) return;
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void modify(int u, int l, int r, int add, int ass){
    if(l > r) return;
    if(l <= tr[u].l && tr[u].r <= r){
        if(ass >= 0) tr[u].mx = tr[u].ass = ass, tr[u].add = 0;
        else tr[u].mx += add, tr[u].add += add;
        return;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(l <= mid) modify(u << 1, l, r, add, ass);
    else modify(u << 1 | 1, l, r, add, ass);
    pushup(u);
}

void modify_path(int u, int v, int add, int ass){
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        modify(1, id[top[u]], id[u], add, ass);
        u = fa[top[u]];
    }
    if(dep[u] < dep[v]) swap(u, v);
    modify(1, id[v] + 1, id[u], add, ass);
}

int query(int u, int l, int r){
    if(l > r) return 0;
    if(l <= tr[u].l && tr[u].r <= r) return tr[u].mx;
    pushdown(u);
    int res = 0;
    int mid = tr[u].l + tr[u].r >> 1;
    if(l <= mid) res = query(u << 1, l, r);
    if(r > mid) res = max(res, query(u << 1 | 1, l, r));
    return res;
}

int query_path(int u, int v){
    int res = 0;
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        res = max(res, query(1, id[top[u]], id[u]));
        u = fa[top[u]];
    }
    if(dep[u] < dep[v]) swap(u, v);
    res = max(res, query(1, id[v] + 1, id[u]));
    return res;
}

int main(){
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb({v, w}), e[v].pb({u, w});
        edges[i] = {u, v};
    }
    dfs1(1, 0), dfs2(1, 1);
    build(1, 1, n);
    while(1){
        char op[10];
        int k, u, v, w;
        scanf("%s", op);
        if(op[0] == 'S') break;
        else if(op[0] == 'M'){
            scanf("%d%d", &u, &v);
            printf("%d\n", query_path(u, v));
        }
        else if(op[1] == 'h'){
            scanf("%d%d", &k, &w);
            if(dep[edges[k].fi] > dep[edges[k].se]) u = edges[k].fi;
            else u = edges[k].se;
            modify(1, id[u], id[u], 0, w);
        }
        else{
            scanf("%d%d%d", &u, &v, &w);
            if(op[0] == 'A') modify_path(u, v, w, -1);
            else modify_path(u, v, 0, w);
        }
    }
    
    return 0;
}
2023/7/2 19:03
加载中...