結果
問題 | No.1030 だんしんぐぱーりない |
ユーザー |
![]() |
提出日時 | 2020-04-17 21:39:56 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 163 ms / 2,000 ms |
コード長 | 9,539 bytes |
コンパイル時間 | 3,029 ms |
コンパイル使用メモリ | 211,044 KB |
最終ジャッジ日時 | 2025-01-09 19:50:20 |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 40 |
ソースコード
#include <bits/stdc++.h>using namespace std;using int64 = long long;const int mod = 1e9 + 7;// const int mod = 998244353;const int64 infll = (1LL << 62) - 1;const int inf = (1 << 30) - 1;struct IoSetup {IoSetup() {cin.tie(nullptr);ios::sync_with_stdio(false);cout << fixed << setprecision(10);cerr << fixed << setprecision(10);}} iosetup;template< typename T1, typename T2 >ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {os << p.first << " " << p.second;return os;}template< typename T1, typename T2 >istream &operator>>(istream &is, pair< T1, T2 > &p) {is >> p.first >> p.second;return is;}template< typename T >ostream &operator<<(ostream &os, const vector< T > &v) {for(int i = 0; i < (int) v.size(); i++) {os << v[i] << (i + 1 != v.size() ? " " : "");}return os;}template< typename T >istream &operator>>(istream &is, vector< T > &v) {for(T &in : v) is >> in;return is;}template< typename T1, typename T2 >inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }template< typename T1, typename T2 >inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }template< typename T = int64 >vector< T > make_v(size_t a) {return vector< T >(a);}template< typename T, typename... Ts >auto make_v(size_t a, Ts... ts) {return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));}template< typename T, typename V >typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {t = v;}template< typename T, typename V >typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {for(auto &e : t) fill_v(e, v);}template< typename F >struct FixPoint : F {FixPoint(F &&f) : F(forward< F >(f)) {}template< typename... Args >decltype(auto) operator()(Args &&... args) const {return F::operator()(*this, forward< Args >(args)...);}};template< typename F >inline decltype(auto) MFP(F &&f) {return FixPoint< F >{forward< F >(f)};}template< typename T = int >struct Edge {int from, to;T cost;int idx;Edge() = default;Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {}operator int() const { return to; }};template< typename T = int >struct Graph {vector< vector< Edge< T > > > g;int es;Graph() = default;explicit Graph(int n) : g(n), es(0) {}size_t size() const {return g.size();}void add_directed_edge(int from, int to, T cost = 1) {g[from].emplace_back(from, to, cost, es++);}void add_edge(int from, int to, T cost = 1) {g[from].emplace_back(from, to, cost, es);g[to].emplace_back(to, from, cost, es++);}void read(int M, int padding = -1, bool weighted = false, bool directed = false) {for(int i = 0; i < M; i++) {int a, b;cin >> a >> b;a += padding;b += padding;T c = T(1);if(weighted) cin >> c;if(directed) add_directed_edge(a, b, c);else add_edge(a, b, c);}}};template< typename T = int >using Edges = vector< Edge< T > >;template< typename Monoid >struct SegmentTree {using F = function< Monoid(Monoid, Monoid) >;int sz;vector< Monoid > seg;const F f;const Monoid M1;SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {sz = 1;while(sz < n) sz <<= 1;seg.assign(2 * sz, M1);}void set(int k, const Monoid &x) {seg[k + sz] = x;}void build() {for(int k = sz - 1; k > 0; k--) {seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);}}void update(int k, const Monoid &x) {k += sz;seg[k] = x;while(k >>= 1) {seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);}}Monoid query(int a, int b) {Monoid L = M1, R = M1;for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {if(a & 1) L = f(L, seg[a++]);if(b & 1) R = f(seg[--b], R);}return f(L, R);}Monoid operator[](const int &k) const {return seg[k + sz];}template< typename C >int find_subtree(int a, const C &check, Monoid &M, bool type) {while(a < sz) {Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);if(check(nxt)) a = 2 * a + type;else M = nxt, a = 2 * a + 1 - type;}return a - sz;}template< typename C >int find_first(int a, const C &check) {Monoid L = M1;if(a <= 0) {if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);return -1;}int b = sz;for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {if(a & 1) {Monoid nxt = f(L, seg[a]);if(check(nxt)) return find_subtree(a, check, L, false);L = nxt;++a;}}return -1;}template< typename C >int find_last(int b, const C &check) {Monoid R = M1;if(b >= sz) {if(check(f(seg[1], R))) return find_subtree(1, check, R, true);return -1;}int a = sz;for(b += sz; a < b; a >>= 1, b >>= 1) {if(b & 1) {Monoid nxt = f(seg[--b], R);if(check(nxt)) return find_subtree(b, check, R, true);R = nxt;}}return -1;}};/*** @brief Heavy-Light-Decomposition(HL分解)* @see https://smijake3.hatenablog.com/entry/2019/09/15/200200*/template< typename T = int >struct HeavyLightDecomposition : Graph< T > {public:using Graph< T >::Graph;using Graph< T >::g;vector< int > sz, in, out, head, rev, par, dep;void build() {sz.assign(g.size(), 0);in.assign(g.size(), 0);out.assign(g.size(), 0);head.assign(g.size(), 0);rev.assign(g.size(), 0);par.assign(g.size(), 0);dep.assign(g.size(), 0);dfs_sz(0, -1, 0);int t = 0;dfs_hld(0, -1, t);}/* k: 0-indexed */int la(int v, int k) {while(1) {int u = head[v];if(in[v] - k >= in[u]) return rev[in[v] - k];k -= in[v] - in[u] + 1;v = par[u];}}int lca(int u, int v) const {for(;; v = par[head[v]]) {if(in[u] > in[v]) swap(u, v);if(head[u] == head[v]) return u;}}int dist(int u, int v) const {return dep[u] + dep[v] - 2 * dep[lca(u, v)];}template< typename E, typename Q, typename F, typename S >E query(int u, int v, const E &ti, const Q &q, const F &f, const S &s, bool edge = false) {E l = ti, r = ti;for(;; v = par[head[v]]) {if(in[u] > in[v]) swap(u, v), swap(l, r);if(head[u] == head[v]) break;l = f(q(in[head[v]], in[v] + 1), l);}return s(f(q(in[u] + edge, in[v] + 1), l), r);}template< typename E, typename Q, typename F >E query(int u, int v, const E &ti, const Q &q, const F &f, bool edge = false) {return query(u, v, ti, q, f, f, edge);}template< typename Q >void add(int u, int v, const Q &q, bool edge = false) {for(;; v = par[head[v]]) {if(in[u] > in[v]) swap(u, v);if(head[u] == head[v]) break;q(in[head[v]], in[v] + 1);}q(in[u] + edge, in[v] + 1);}/* {parent, child} */vector< pair< int, int > > compress(vector< int > &remark) {auto cmp = [&](int a, int b) { return in[a] < in[b]; };sort(begin(remark), end(remark), cmp);remark.erase(unique(begin(remark), end(remark)), end(remark));int K = (int) remark.size();for(int k = 1; k < K; k++) remark.emplace_back(lca(remark[k - 1], remark[k]));sort(begin(remark), end(remark), cmp);remark.erase(unique(begin(remark), end(remark)), end(remark));vector< pair< int, int > > es;stack< int > st;for(auto &k : remark) {while(!st.empty() && out[st.top()] <= in[k]) st.pop();if(!st.empty()) es.emplace_back(st.top(), k);st.emplace(k);}return es;}explicit HeavyLightDecomposition(const Graph< T > &g) : Graph< T >(g) {}private:void dfs_sz(int idx, int p, int d) {dep[idx] = d;par[idx] = p;sz[idx] = 1;if(g[idx].size() && g[idx][0] == p) swap(g[idx][0], g[idx].back());for(auto &to : g[idx]) {if(to == p) continue;dfs_sz(to, idx, d + 1);sz[idx] += sz[to];if(sz[g[idx][0]] < sz[to]) swap(g[idx][0], to);}}void dfs_hld(int idx, int p, int ×) {in[idx] = times++;rev[in[idx]] = idx;for(auto &to : g[idx]) {if(to == p) continue;head[to] = (g[idx][0] == to ? head[idx] : to);dfs_hld(to, idx, times);}out[idx] = times;}};int main() {int N, K, Q;cin >> N >> K >> Q;vector< int > C(N);cin >> C;vector< int > A(K);cin >> A;for(auto &p : A) --p;HeavyLightDecomposition< int > g(N);g.read(N - 1);g.build();auto f1 = [](int a, int b) { return min(a, b); };auto f2 = [](int a, int b) { return max(a, b); };SegmentTree< int > seg1(K, f1, inf), seg2(K, f2, -inf), seg3(N, f2, -inf);for(int i = 0; i < K; i++) {seg1.set(i, g.in[A[i]]);seg2.set(i, g.in[A[i]]);}for(int i = 0; i < N; i++) {seg3.set(g.in[i], C[i]);}seg1.build();seg2.build();seg3.build();while(Q--) {int t, a, b;cin >> t >> a >> b;if(t == 1) {--a, --b;seg1.update(a, g.in[b]);seg2.update(a, g.in[b]);} else {--a;int x = seg1.query(a, b);int y = seg2.query(a, b);int lca = g.lca(g.rev[x], g.rev[y]);cout << g.query(lca, 0, -inf, [&](int a, int b) { return seg3.query(a, b); }, [](int a, int b) { return max(a, b); }) << "\n";}}}