1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| #include <bits/stdc++.h> using namespace std;
#define int long long #define Mid ((L+R) >> 1) #define ls (u<<1) #define rs (u<<1|1) const int N = 500010;
struct Edge { int to, nxt, w; } e[N<<1];
struct Query { int id, a, b, k; bool operator<(const Query& q) const { return k < q.k; } } qry[N];
struct Point { int w, v; bool operator<(const Point& p) const { return w < p.w; } } points[N];
int n, q, h[N], w[N], d[N], f[N], g[N], p[N], sz[N], ans[N], seq[N<<1], idx = 2, sidx; int mn[N<<3], mx[N<<3], au[N<<3], ua[N<<3], diam[N<<3], tag[N<<3];
void add(int a, int b, int c) { e[idx] = {b, h[a], c}, h[a] = idx++; }
void dfs(int u) { sz[u] = 1; seq[f[u] = g[u] = ++sidx] = u; for (int i = h[u]; i; i = e[i].nxt) { int to = e[i].to; if (f[to]) continue; p[i >> 1] = to; d[to] = d[u] + e[i].w; w[to] = e[i].w; dfs(to); sz[u] += sz[to]; seq[g[u] = ++sidx] = u; } points[u] = {min(sz[u], n - sz[u]), u}; }
void pushup(int u) { diam[u] = max(max(diam[ls], diam[rs]), max(au[ls] + mx[rs], mx[ls] + ua[rs])); au[u] = max(max(au[ls], au[rs]), mx[ls] - 2 * mn[rs]); ua[u] = max(max(ua[ls], ua[rs]), mx[rs] - 2 * mn[ls]); mx[u] = max(mx[ls], mx[rs]); mn[u] = min(mn[ls], mn[rs]); }
void spread(int u, int k) { mx[u] += k, mn[u] += k, tag[u] += k, au[u] -= k, ua[u] -= k; }
void pushdown(int u) { if (!tag[u]) return; spread(ls, tag[u]); spread(rs, tag[u]); tag[u] = 0; }
void build(int u, int L, int R) { if (L == R) { mn[u] = mx[u] = d[seq[L]]; au[u] = ua[u] = -d[seq[L]]; diam[u] = 0; return; } build(ls, L, Mid), build(rs, Mid+1, R); pushup(u); }
void modify(int u, int l, int r, int k, int L, int R) { if (l <= L && R <= r) return spread(u, k); pushdown(u); if (l <= Mid) modify(ls, l, r, k, L, Mid); if (Mid+1 <= r) modify(rs, l, r, k, Mid+1, R); pushup(u); }
void change(int u, int k) { if (w[u] == 0) return; modify(1, f[u], g[u], k - w[u], 1, sidx); w[u] = k; }
signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> n >> q;
for (int i = 1, a, b, c; i < n; i++) { cin >> a >> b >> c; add(a, b, c), add(b, a, c); }
for (int i = 1, a, b, k; i <= q; i++) { cin >> a >> b >> k; qry[i] = {i, a, b, k}; } dfs(1); build(1, 1, sidx);
sort(qry+1, qry+1+q); sort(points+1, points+1+n); for (int i = 1, j = 1, a, b, k; i <= q; i++) { a = qry[i].a, b = qry[i].b, k = qry[i].k; while (points[j].w < k && j <= n) change(points[j++].v, 0); int old = w[p[a]]; change(p[a], b); ans[qry[i].id] = diam[1]; change(p[a], old); }
for (int i = 1; i <= q; i++) cout << ans[i] << '\n'; return 0; }
|