제출 #1114034

#제출 시각아이디문제언어결과실행 시간메모리
1114034vjudge1Birthday gift (IZhO18_treearray)C++17
56 / 100
4059 ms45256 KiB
#include <bits/stdc++.h> using i64 = long long; #ifdef DEBUG #include "/home/ahmetalp/Desktop/Workplace/debug.h" #else #define debug(...) void(23) #endif constexpr int max_N = int(2E5) + 5; constexpr int LG = 20; int N, M, Q; std::vector<int> adj[max_N]; int par[LG][max_N], tin[max_N], tout[max_N], dep[max_N], timer; void dfs(int v) { tin[v] = timer++; for (auto u : adj[v]) { adj[u].erase(std::find(adj[u].begin(), adj[u].end(), v)); par[0][u] = v; dep[u] = dep[v] + 1; dfs(u); } tout[v] = timer; } bool is_in_subtree_of(int u, int v) { return tin[v] <= tin[u] && tout[u] <= tout[v]; } int lca(int a, int b) { if (is_in_subtree_of(a, b)) { return b; } else if (is_in_subtree_of(b, a)) { return a; } for (int lg = LG - 1; lg >= 0; --lg) { if (!is_in_subtree_of(b, par[lg][a])) { a = par[lg][a]; } } return par[0][a]; } int A[max_N]; #define def int mid = (l + r) >> 1, lv = v << 1, rv = v << 1 | 1; struct node { int v; } tree[max_N << 2]; node unite(const node& lhs, const node& rhs) { return {lca(lhs.v, rhs.v)}; } void build(int v, int l, int r) { if (l == r) { tree[v] = {A[l]}; return; } def; build(lv, l, mid); build(rv, mid + 1, r); tree[v] = unite(tree[lv], tree[rv]); } void build() { build(1, 0, M - 1); } void modify(int v, int l, int r, int p, int x) { if (l == r) { tree[v] = {x}; return; } def; if (p <= mid) { modify(lv, l, mid, p, x); } else { modify(rv, mid + 1, r, p, x); } tree[v] = unite(tree[lv], tree[rv]); } void modify(int p, int x) { modify(1, 0, M - 1, p, x); } node query(int v, int l, int r, int ql, int qr) { if (l == ql && qr == r) { return tree[v]; } def; if (qr <= mid) { return query(lv, l, mid, ql, qr); } else if (mid + 1 <= ql) { return query(rv, mid + 1, r, ql, qr); } else { return unite(query(lv, l, mid, ql, mid), query(rv, mid + 1, r, mid + 1, qr)); } } node query(int l, int r) { return query(1, 0, M - 1, l, r); } std::pair<int, int> find_first(int v, int l, int r, int p, int now, int x) { debug("finding first", v, l, r, p, now, x); if (r < p) { return {-1, -1}; } else if (l == r) { int tv = lca(now, tree[v].v); return {tv, l}; } else if (p <= l) { def; int tv = tree[lv].v; int lc = lca(tv, now); if (dep[lc] > dep[x]) { return find_first(rv, mid + 1, r, p, lc, x); } else { return find_first(lv, l, mid, p, now, x); } } def; auto gl = find_first(lv, l, mid, p, now, x); if (gl.first != -1) { if (dep[gl.first] <= dep[x]) { return gl; } now = lca(now, gl.first); } auto gr = find_first(rv, mid + 1, r, p, now, x); return gr; } std::pair<int, int> find_first(int p, int x) { return find_first(1, 0, M - 1, p, A[p], x); } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cin >> N >> M >> Q; for (int i = 1; i < N; ++i) { int X, Y; std::cin >> X >> Y; adj[X].emplace_back(Y); adj[Y].emplace_back(X); } for (int i = 0; i < M; ++i) { std::cin >> A[i]; } par[0][1] = 1; dfs(1); #ifdef DEBUG for (int i = 1; i <= N; ++i) { std::cerr << par[0][i] << " \n"[i == N]; } for (int i = 1; i <= N; ++i) { std::cerr << dep[i] << " \n"[i == N]; } for (int i = 1; i <= N; ++i) { std::cerr << tin[i] << " \n"[i == N]; } for (int i = 1; i <= N; ++i) { std::cerr << tout[i] << " \n"[i == N]; } #endif for (int lg = 0; lg + 1 < LG; ++lg) { for (int i = 1; i <= N; ++i) { par[lg + 1][i] = par[lg][par[lg][i]]; } } build(); while (Q--) { int TP; std::cin >> TP; if (TP == 1) { int P, X; std::cin >> P >> X; --P; A[P] = X; modify(P, X); } else { int L, R, X; std::cin >> L >> R >> X; --L, --R; bool found = false; for (int l = L; l <= R; ++l) { auto[x, r] = find_first(l, X); debug(l, x, r); if (x == X && r <= R) { std::cout << l + 1 << ' ' << r + 1 << '\n'; found = true; break; } } if (!found) { std::cout << "-1 -1\n"; } } debug(); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...