树剖爆零求助
查看原帖
树剖爆零求助
369363
yjiong楼主2023/3/11 10:10

rt,请dalao帮忙看看

#include <bits/stdc++.h>
#define ls(x) x << 1
#define rs(x) (x << 1) | 1

const int sp = 1e6 + 5;

struct sg_tr{
    int l, r, dat;
}tr[sp];

int tag1[sp], tag2[sp];
int dep[sp], fa[sp], hson[sp], siz[sp];
int tp[sp];
int id[sp], tot;
int u[sp], v[sp], w[sp], ww[sp], tmp[sp];
int n;
std::string s;
std::vector <int> mp[sp];

void get_info(int x, int f){
    fa[x] = f;
    dep[x] = dep[f] + 1;
    siz[x] = 1;
    int maxn = 0;
    for(int i = 0; i < mp[x].size(); ++ i){
        int y = mp[x][i];
        if(y == f){
            continue;
        }
        get_info(y, x);
        siz[x] += siz[y];
        if(siz[y] > maxn){
            maxn = siz[y];
            hson[x] = y;
        }
    }
    return;
}

void get_tp(int x, int ttp){
    tp[x] = ttp;
    id[x] = ++ tot;
    w[id[x]] = ww[x];
    if(hson[x] == 0){
        return;
    }
    get_tp(hson[x], ttp);
    for(int i = 0; i < mp[x].size(); ++ i){
        int y = mp[x][i];
        if(y == fa[x] || y == hson[x]){
            continue;
        }
        get_tp(y, y);
    }
    return;
}

void pushup(int p){
    tr[p].dat = std::max(tr[ls(p)].dat, tr[rs(p)].dat);
    return;
}

void build(int p, int l, int r){
    tr[p].l = l, tr[p].r = r;
    if(l == r){
        tr[p].dat = w[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(ls(p), l, mid);
    build(rs(p), mid + 1, r);
    pushup(p);
    return;
}

void tagdown1(int p){
    tag1[ls(p)] = tag1[rs(p)] = tag1[p];
    tr[ls(p)].dat = tr[rs(p)].dat = tag1[p];
    tag1[p] = -1;
    return;
}

void tagdown2(int p){
    tag2[ls(p)] += tag2[p];
    tag2[rs(p)] += tag2[p];
    tr[ls(p)].dat += tag2[p];
    tr[rs(p)].dat += tag2[p];
    tag2[p] = 0;
    return;
}

void update1(int p, int dl, int dr, int k){
    if(tr[p].l > dr || tr[p].r < dl){
        return;
    }
    if(tag1[p] != -1){
        tagdown1(p);
    }
    if(tag2[p] != 0){
        tagdown2(p);
    }
    if(tr[p].l >= dl && tr[p].r <= dr){
        tag1[p] = k;
        tr[p].dat = k;
        return;
    }
    update1(ls(p), dl, dr, k);
    update1(rs(p), dl, dr, k);
    pushup(p);
    return;
}

void update2(int p, int dl, int dr, int k){
    if(tr[p].l > dr || tr[p].r < dl){
        return;
    }
    if(tag1[p] != -1){
        tagdown1(p);
    }
    if(tag2[p] != 0){
        tagdown2(p);
    }
    if(tr[p].l >= dl && tr[p].r <= dr){
        tag2[p] += k;
        tr[p].dat += k;
        return;
    }
    update2(ls(p), dl, dr, k);
    update2(rs(p), dl, dr, k);
    pushup(p);
    return;
}

int query(int p, int dl, int dr){
    if(tr[p].l > dr || tr[p].r < dl){
        return 0;
    }
    if(tag1[p] != -1){
        tagdown1(p);
    }
    if(tag2[p] != 0){
        tagdown2(p);
    }
    if(tr[p].l >= dl && tr[p].r <= dr){
        return tr[p].dat;
    }
    int ret = std::max(query(ls(p), dl, dr), query(rs(p), dl, dr));
    pushup(p);
    return ret;
}

void _cover(int x, int y, int z){
    while(tp[x] != tp[y]){
        if(dep[tp[x]] < dep[tp[y]]){
            std::swap(x, y);
        }
        update1(1, id[tp[x]], id[x], z);
        x = fa[tp[x]];
    }
    if(dep[x] < dep[y]){
        std::swap(x, y);
    }
    if(x != y){
        update1(1, id[y] + 1, id[x], z);
    }
    return;
}

void _add(int x, int y, int z){
    while(tp[x] != tp[y]){
        if(dep[tp[x]] < dep[tp[y]]){
            std::swap(x, y);
        }
        update2(1, id[tp[x]], id[x], z);
        x = fa[tp[x]];
    }
    if(dep[x] < dep[y]){
        std::swap(x, y);
    }
    if(x != y){
        update2(1, id[y] + 1, id[x], z);
    }
    return;
}

void _query(int x, int y){
    int ans = 0;
    while(tp[x] != tp[y]){
        if(dep[tp[x]] < dep[tp[y]]){
            std::swap(x, y);
        }
        ans = std::max(ans, query(1, id[tp[x]], id[x]));
        x = fa[tp[x]];
    }
    if(dep[x] < dep[y]){
        std::swap(x, y);
    }
    if(x != y){
        ans = std::max(ans, query(1, id[y] + 1, id[x]));
    }
    std::cout << ans << "\n";
    return;
}

int main(){
    std::cin >> n;
    memset(tag1, -1, sizeof(tag1));
    for(int i = 1; i < n; ++ i){
        std::cin >> u[i] >> v[i] >> tmp[i];
        mp[u[i]].push_back(v[i]);
        mp[v[i]].push_back(u[i]);
    }
    get_info(1, 0);
    for(int i = 1; i < n; ++ i){
        if(dep[u[i]] < dep[v[i]]){
            ww[v[i]] = tmp[i];
        }
        else{
            ww[u[i]] = tmp[i];
        }
    }
    get_tp(1, 1);
    build(1, 1, n);
    while(std::cin >> s){
        if(s == "Stop"){
            break;
        }
        if(s == "Change"){
            int x, y;
            std::cin >> x >> y;
            if(dep[u[x]] < dep[v[x]]){
                update1(1, id[v[x]], id[v[x]], y);
            }
            else{
                update1(1, id[u[x]], id[u[x]], y);
            }
        }
        if(s == "Cover"){
            int x, y, z;
            std::cin >> x >> y >> z;
            _cover(x, y, z);
        }
        if(s == "Add"){
            int x, y, z;
            std::cin >> x >> y >> z;
            _add(x, y, z);
        }
        if(s == "Max"){
            int x, y;
            std::cin >> x >> y;
            _query(x, y);
        }
    }
    return 0;
}
2023/3/11 10:10
加载中...