1 条题解
-
1
相信开这道题的神犇一定会树剖,但是树剖一般是维护的点权,所以对于边权,我们将该边的边权存到这条边所连的两个点中更深的那个点就好了。
注意边界!!!
我用的珂朵莉树,大概 ,实测能过。
code:
# include <bits/stdc++.h> # define int long long using namespace std; struct node { long long l, r; mutable long long v; node (long long l, long long r = 0, long long v = 0) : l (l), r (r), v (v) {} bool operator < (const node &other) const { return l < other.l; } }; set <node> tree; inline set<node> :: iterator split (register long long pos) { set <node> :: iterator it = tree.lower_bound (node (pos)); if (it != tree.end () and it -> l == pos) return it; it --; if (it -> r < pos) return tree.end(); register long long l = it -> l; register long long r = it -> r; register long long v = it -> v; tree.erase (it), tree.insert (node (l, pos - 1, v)); return tree.insert (node (pos, r, v)).first; } inline void cover (int l, int r, int x) { set <node> :: iterator rr = split (r + 1), ll = split (l); tree.erase (ll, rr); tree.insert (node (l, r, x)); return; } inline void add (int l, int r, int x) { // cout << l << ' ' << r << endl; set <node> :: iterator rr = split (r + 1), ll = split (l); for (auto it = ll; it != rr; it ++) it -> v += x; } int find (int l, int r) { set <node> :: iterator rr = split (r + 1); set <node> :: iterator ll = split (l); int ret = 0; for (auto it = ll; it != rr; it ++) { ret = max (ret, it -> v); } return ret; } int depth[200012], fa[200012], s[200012], son[200012]; int pos, id[200012], top[200012]; vector <int> e[200012]; int w[200012], num[200012]; int n; inline void dfs1 (int u, int father,int dep){ depth[u] = dep; fa[u] = father; s[u] = 1; int ch = -1; for(unsigned int i = 0; i < e[u].size (); i ++) { int v = e[u][i]; if (v == father) { continue; } dfs1 (v, u, dep + 1); s[u] += s[v]; if (s[v] > ch) { son[u] = v; ch = s[v]; } } } inline void dfs2 (int u, int father) { ++ pos; id[u] = pos; num[pos] = w[u]; top[u] = father; if (not son[u]) { return; } dfs2 (son[u], father); for(unsigned int i = 0; i < e[u].size (); i ++) { int v = e[u][i]; if (v == fa[u] or v == son[u]) { continue; } dfs2 (v, v); } } void amend (int u, int v, int x) { while (top[u] != top[v]) { if (depth[top[u]] < depth[top[v]]) { swap (u, v); } // cout << u << ' ' << v << endl; add (id[top[u]], id[u], x); u = fa[top[u]]; } if (depth[u] > depth[v]) swap (u, v); if (u == v) return; // cout << id[u] + 1 << ' ' << id[v] << endl; add (id[u] + 1, id[v], x); } void change (int u, int v, int x) { while (top[u] != top[v]) { if (depth[top[u]] < depth[top[v]]) { swap (u, v); } cover (id[top[u]], id[u], x); u = fa[top[u]]; } if (u == v) return; if (depth[u] > depth[v]) swap (u, v); cover (id[u] + 1, id[v], x); } long long mx (int u, int v) { int ret = 0; while (top[u] != top[v]) { if (depth[top[u]] < depth[top[v]]) { swap (u, v); } ret = max (ret, find (id[top[u]], id[u])); u = fa[top[u]]; } if (depth[u] > depth[v]) swap (u, v); ret = max (ret, find (id[u] + 1, id[v])); return ret; } struct path { int u, v, w; }a[200012]; signed main () { ios :: sync_with_stdio (0); cin.tie (0), cout.tie (0); cin >> n; for (int i = 1; i < n; i ++) { cin >> a[i].u >> a[i].v >> a[i].w; e[a[i].u].push_back (a[i].v); e[a[i].v].push_back (a[i].u); } dfs1 (1, 0, 0); dfs2 (1, 0); for (int i = 1; i <= n; i ++) { int u = a[i].u, v = a[i].v, weight = a[i].w; if (fa[v] == u) { w[v] = weight; num[id[v]] = w[v]; } else { w[u] = weight; num[id[u]] = w[u]; } } tree.insert (node (1, n, 0)); for (int i = 1; i <= n; i ++) cover (i, i, num[i]); // cout << id[2] << ' ' << num[id[2]] << endl; while (true) { string op; cin >> op; if (op == "Stop") break; if (op == "Cover") { int u, v, x; cin >> u >> v >> x; if (u == v) continue; change (u, v, x); } else if (op == "Change") { int k, x; cin >> k >> x; int u = a[k].u; int v = a[k].v; change (u, v, x); } else if (op == "Add") { int u, v, x; cin >> u >> v >> x; if (u == v) continue; amend (u, v, x); } else { int u, v; cin >> u >> v; cout << mx (u, v) << "\n"; } } }
- 1
信息
- ID
- 8342
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 3
- 已通过
- 3
- 上传者