結果
問題 | No.1030 だんしんぐぱーりない |
ユーザー | risujiroh |
提出日時 | 2020-04-17 22:09:50 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 139 ms / 2,000 ms |
コード長 | 5,636 bytes |
コンパイル時間 | 3,101 ms |
コンパイル使用メモリ | 226,972 KB |
実行使用メモリ | 16,360 KB |
最終ジャッジ日時 | 2024-10-03 13:17:57 |
合計ジャッジ時間 | 7,851 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 1 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 102 ms
14,080 KB |
testcase_06 | AC | 77 ms
11,656 KB |
testcase_07 | AC | 48 ms
6,884 KB |
testcase_08 | AC | 51 ms
8,104 KB |
testcase_09 | AC | 88 ms
14,624 KB |
testcase_10 | AC | 33 ms
5,248 KB |
testcase_11 | AC | 81 ms
9,292 KB |
testcase_12 | AC | 91 ms
13,216 KB |
testcase_13 | AC | 74 ms
11,860 KB |
testcase_14 | AC | 93 ms
11,824 KB |
testcase_15 | AC | 37 ms
5,248 KB |
testcase_16 | AC | 83 ms
10,424 KB |
testcase_17 | AC | 93 ms
14,660 KB |
testcase_18 | AC | 101 ms
12,464 KB |
testcase_19 | AC | 55 ms
6,272 KB |
testcase_20 | AC | 69 ms
9,084 KB |
testcase_21 | AC | 69 ms
11,444 KB |
testcase_22 | AC | 67 ms
9,412 KB |
testcase_23 | AC | 76 ms
8,888 KB |
testcase_24 | AC | 53 ms
5,760 KB |
testcase_25 | AC | 68 ms
8,764 KB |
testcase_26 | AC | 41 ms
5,248 KB |
testcase_27 | AC | 46 ms
5,248 KB |
testcase_28 | AC | 89 ms
10,816 KB |
testcase_29 | AC | 74 ms
13,060 KB |
testcase_30 | AC | 64 ms
9,712 KB |
testcase_31 | AC | 65 ms
8,756 KB |
testcase_32 | AC | 82 ms
11,564 KB |
testcase_33 | AC | 91 ms
13,388 KB |
testcase_34 | AC | 33 ms
5,504 KB |
testcase_35 | AC | 132 ms
16,360 KB |
testcase_36 | AC | 132 ms
16,356 KB |
testcase_37 | AC | 133 ms
16,360 KB |
testcase_38 | AC | 139 ms
16,360 KB |
testcase_39 | AC | 136 ms
16,360 KB |
testcase_40 | AC | 2 ms
5,248 KB |
testcase_41 | AC | 2 ms
5,248 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; #ifdef LOCAL #include "debug.h" #else #define DEBUG(...) #endif template <class T> struct tree { struct edge { int u, v; T w; }; int n; vector<edge> es; vector<vector<int>> g; vector<int> pv, pe, sz, dep, vs, in, out, head; vector<T> dist; tree(int _n = 0) : n(_n), g(n) {} void add(int u, int v, T w = 1) { g[u].push_back(es.size()), g[v].push_back(es.size()); es.push_back({u, v, w}); } int other(int id, int v) const { return es[id].u ^ es[id].v ^ v; } void dfs(int v) { sz[v] = 1; for (int id : g[v]) { if (id == pe[v]) continue; int to = other(id, v); assert(pv[to] == -1); pv[to] = v, pe[to] = id; dep[to] = dep[v] + 1, dist[to] = dist[v] + es[id].w; dfs(to); sz[v] += sz[to]; } sort(begin(g[v]), end(g[v]), [&](int a, int b) { return sz[other(a, v)] * (a != pe[v]) > sz[other(b, v)] * (b != pe[v]); }); } void build(int r = 0) { assert((int)es.size() == n - 1); pv.assign(n, -1), pe.resize(n), sz.resize(n), dep.resize(n), dist.resize(n); pe[r] = -1, dep[r] = 0, dist[r] = 0; dfs(r); } void dfs_hld(int v) { in[v] = vs.size(), vs.push_back(v); for (int id : g[v]) { if (id == pe[v]) continue; int to = other(id, v); head[to] = to == other(g[v][0], v) ? head[v] : to; dfs_hld(to); } out[v] = vs.size(); } void build_hld(int r = 0) { build(r); vs.clear(), in.resize(n), out.resize(n), head.resize(n); head[r] = r; dfs_hld(r); } bool anc(int u, int v) const { return in[u] <= in[v] and out[v] <= out[u]; } int lca(int u, int v) const { while (true) { if (in[u] > in[v]) swap(u, v); if (head[u] == head[v]) return u; v = pv[head[v]]; } } int d(int u, int v) const { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; } T len(int u, int v) const { return dist[u] + dist[v] - 2 * dist[lca(u, v)]; } int la(int v, int d) const { assert(0 <= d and d <= dep[v]); while (dep[head[v]] > d) v = pv[head[v]]; return vs[in[head[v]] + (d - dep[head[v]])]; } int next(int from, int to) const { assert(from != to); if (not anc(from, to)) return pv[from]; return la(to, dep[from] + 1); } vector<pair<int, int>> ascend(int from, int to) const { vector<pair<int, int>> res; while (head[from] != head[to]) { res.emplace_back(in[from], in[head[from]]); from = pv[head[from]]; } if (from != to) res.emplace_back(in[from], in[to] + 1); return res; } vector<pair<int, int>> descend(int from, int to) const { if (from == to) return {}; if (head[from] == head[to]) return {{in[from] + 1, in[to]}}; auto res = descend(from, pv[head[to]]); res.emplace_back(in[head[to]], in[to]); return res; } template <class F> void run(int from, int to, F f, bool vertex = true) const { int v = lca(from, to); for (auto e : ascend(from, v)) f(e.first + 1, e.second); if (vertex) f(in[v], in[v] + 1); for (auto e : descend(v, to)) f(e.first, e.second + 1); } template <class Node> vector<Node> dp(int r = 0) { build_hld(r); vector<Node> lower(n - 1), upper(n - 1), res(n); vector<vector<Node>> cum(n); for (int t = n; t--; ) { int v = vs[t], m = g[v].size() - (v != r); cum[v].resize(m + 1); for (int i = m; i--; ) cum[v][i] = lower[g[v][i]] + cum[v][i + 1]; if (v != r) lower[pe[v]] = cum[v][0].add(v, pe[v]); } for (int v : vs) { Node cur = v != r ? upper[pe[v]] : Node(); for (int i = 0, m = cum[v].size() - 1; i < m; ++i) { upper[g[v][i]] = (cur + cum[v][i + 1]).add(v, g[v][i]); cur = cur + lower[g[v][i]]; } res[v] = cur.add(v); } return res; } }; template <class T> struct segtree { const int n; vector<T> t; segtree(int _n = 0) : n(_n), t(2 * n) {} T& operator[](int i) { return t[n + i]; } void build() { for (int i = n; i--; ) t[i] = t[2 * i] * t[2 * i + 1]; } T fold(int l, int r) const { T a, b; for (l += n, r += n; l < r; l >>= 1, r >>= 1) { if (l & 1) a = a * t[l++]; if (r & 1) b = t[--r] * b; } return a * b; } void set(int i, T a) { t[i += n] = a; while (i >>= 1) t[i] = t[2 * i] * t[2 * i + 1]; } }; tree<int> g; struct node { int v = -1; node operator*(node b) const { if (v == -1) { return b; } if (b.v == -1) { return *this; } return {g.lca(v, b.v)}; } }; struct maxi { int v = -1; maxi operator*(maxi b) const { return {max(v, b.v)}; } }; int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int n, k, q; cin >> n >> k >> q; vector<int> c(n); for (auto&& e : c) { cin >> e; } vector<int> a(k); for (auto&& e : a) { cin >> e; --e; } g = tree<int>(n); for (int i = 0; i < n - 1; ++i) { int u, v; cin >> u >> v; --u, --v; g.add(u, v); } g.build_hld(); segtree<node> seg(k); for (int i = 0; i < k; ++i) { seg[i] = {a[i]}; } seg.build(); segtree<maxi> mx(n); for (int v = 0; v < n; ++v) { mx[g.in[v]] = {c[v]}; } mx.build(); while (q--) { int t; cin >> t; if (t == 1) { int x, y; cin >> x >> y; --x, --y; seg.set(x, {y}); } else { int l, r; cin >> l >> r; --l; int res = -1; DEBUG(seg.fold(l, r).v); g.run(seg.fold(l, r).v, 0, [&](int ll, int rr) { if (ll > rr) { swap(ll, rr); } res = max(res, mx.fold(ll, rr).v); }); cout << res << '\n'; } } }