RE求助
查看原帖
RE求助
366937
too_simple楼主2023/3/7 22:14
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

#define int long long

using namespace std;

const int N = 2e5 + 50, INF = 123456789123456789;

int n, m;
int h[N], ne[N * 2], e[N * 2], w[N * 2], idx;
int fa[N], son[N], dist[N], dep[N], sz[N];
int id[N], cnt, top[N], rk[N];

struct Line {
    int k, b;
    Line() {}
    Line(int x, int y) {k = x, b = y;}
};

struct Tree {
    Line seg;
    int val, l, r;
}tr[N << 3];

inline int calc(Line l, int x) {
    return l.k * x + l.b;
}

void add(int a, int b, int c) {
    ne[idx] = h[a], e[idx] = b, w[idx] = c, h[a] = idx ++;
}

void dfs(int u, int fath) {
    fa[u] = fath, dep[u] = dep[fath] + 1, sz[u] = 1;
    for(int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if(j == fath) continue;
        dist[j] = dist[u] + w[i];
        dfs(j, u);
        sz[u] += sz[j];
        if(sz[j] > sz[son[u]]) son[u] = j;
    }
}

void dfs1(int u, int t) {
    id[u] = ++ cnt, top[u] = t, rk[cnt] = u;
    if(!son[u]) return ;
    dfs1(son[u], t);
    for(int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if(j == fa[u] || j == son[u]) continue;
        dfs1(j, j);
    }
}

inline int LCA(int u, int v) {
    while(top[u] != top[v]) {
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        u = fa[top[u]];
    }
    return dep[u] < dep[v] ? u : v;
}

void pushup(int u) {
    tr[u].val = min(tr[u].val, min(calc(tr[u].seg, dist[rk[tr[u].l]]), calc(tr[u].seg, dist[rk[tr[u].r]])));
    tr[u].val = min(tr[u].val, min(tr[tr[u].l].val, tr[tr[u].r].val));
}

void build(int u, int l, int r) {
    tr[u].seg.k = 0, tr[u].seg.b = INF;
    tr[u].val = INF, tr[u].l = l, tr[u].r = r;
    if(l == r) return ;
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}

void modify(int u, int s, int t, Line l) {
    if(t < tr[u].l || s > tr[u].r) return ;
    if(s <= tr[u].l && tr[u].r <= t) {
        int mid = tr[u].l + tr[u].r >> 1;
        if(calc(l, dist[rk[mid]]) < calc(tr[u].seg, dist[rk[mid]])) swap(tr[u].seg, l);
        if(calc(l, dist[rk[tr[u].l]] < calc(tr[u].seg, dist[rk[tr[u].l]]))) modify(u << 1, s, t, l);
        if(calc(l, dist[rk[tr[u].r]] < calc(tr[u].seg, dist[rk[tr[u].r]]))) modify(u << 1 | 1, s, t, l);
        return pushup(u), void();
    }
    modify(u << 1, s, t, l), modify(u << 1 | 1, s, t, l);
    pushup(u);
}

int query(int u, int s, int t) {
    if(s <= tr[u].l && tr[u].r <= t) return tr[u].val;
    int mid = tr[u].l + tr[u].r >> 1;
    int ans = min(calc(tr[u].seg, dist[rk[max(tr[u].l, s)]]), calc(tr[u].seg, dist[rk[min(tr[u].r, t)]]));
    if(s <= mid) ans = min(ans, query(u << 1, s, t));
    if(mid < t) ans = min(ans, query(u << 1 | 1, s, t));
    return ans;
}

int modifytree(int u, int v, Line l) {
    while(top[u] != top[v]) {
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        modify(1, id[top[u]], id[u], l);
        u = fa[top[u]];
    }
    if(dep[u] < dep[v]) swap(u, v);
    modify(1, id[v], id[u], l);
}

int querytree(int u, int v) {
    int ans = INF;
    while(top[u] != top[v]) {
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        ans = min(ans, query(1, id[top[u]], id[u]));
        u = fa[top[u]];
    }
    if(dep[u] < dep[v]) swap(u, v);
    ans = min(ans, query(1, id[v], id[u]));
    return ans;
}

signed main() {
    
    memset(h, -1, sizeof h);
    
    cin >> n >> m;
    
    build(1, 1, n);
    
    for(int i = 1; i < n; ++ i) {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }
    
    dfs(1, 0), dfs1(1, 1);
    
    while(m -- ) {
        int op;
        cin >> op;
        if(op == 1) {
            int s, t, a, b;
            cin >> s >> t >> a >> b;
            int lca = LCA(s, t);
            modifytree(s, lca, Line (-a, a * dist[s] + b));
            modifytree(lca, t, Line (a, a * dist[s] - 2 * a * dist[lca] + b));
        }
        else {
            int s, t;
            cin >> s >> t;
            cout << querytree(s, t) << endl;
        }
    }
    
    return 0;
}
2023/3/7 22:14
加载中...