제출 #685521

#제출 시각아이디문제언어결과실행 시간메모리
685521speedyArdaBirthday gift (IZhO18_treearray)C++14
56 / 100
369 ms39396 KiB
#include "bits/stdc++.h" using namespace std; const int MAXN = 2e5+5; int seglca[MAXN * 4], segans[MAXN * 4], in[MAXN], out[MAXN], height[MAXN], seq[MAXN]; vector<int> euler; vector< vector<int> > adj(MAXN); void dfs(int v, int p, int h) { in[v] = euler.size(); euler.push_back(v); height[v] = h; for(int e : adj[v]) { if(e == p) continue; dfs(e, v, h + 1); euler.push_back(v); } out[v] = euler.size() - 1; } void buildlca(int v, int tl, int tr) { if(tl == tr) { seglca[v] = euler[tl]; //cout << v << " " << tl << " " << tr << " " << seglca[v] << "\n"; return; } int tm = (tl + tr) / 2; buildlca(2 * v, tl, tm); buildlca(2 * v + 1, tm + 1, tr); if(height[seglca[v * 2]] < height[seglca[v * 2 + 1]]) seglca[v] = seglca[v * 2]; else seglca[v] = seglca[v * 2 + 1]; //cout << v << " " << tl << " " << tr << " " << seglca[v * 2] << " " << seglca[2 * v + 1] << " " << in[seglca[v * 2]] << " " << in[seglca[v * 2 + 1]] << " " << seglca[v] << "\n"; } int getlca(int v, int tl, int tr, int l, int r) { if(l > r) return -1; if(tl == l && tr == r) return seglca[v]; int tm = (tl + tr) / 2; int left = getlca(2 * v, tl, tm, l, min(r, tm)), right = getlca(2 * v + 1, tm + 1, tr, max(l, tm + 1), r); if(right == -1) return left; if(left == -1) return right; if(height[left] < height[right]) return left; else return right; } int lca(int a, int b) { if(in[a] > in[b]) swap(a, b); return getlca(1, 0, euler.size() - 1, in[a], in[b]); } void buildans(int v, int tl, int tr) { if(tl == tr) { segans[v] = seq[tl]; return; } int tm = (tl + tr) / 2; buildans(2 * v, tl, tm); buildans(2 * v + 1, tm + 1, tr); segans[v] = lca(segans[v * 2], segans[v * 2 + 1]); } void updateans(int v, int tl, int tr, int pos, int val) { if(tl == tr) { segans[v] = val; return; } int tm = (tl + tr) / 2; if(tm >= pos) updateans(2 * v, tl, tm, pos, val); else updateans(2 * v + 1, tm + 1, tr, pos, val); segans[v] = lca(segans[2 * v], segans[2 * v + 1]); } int getans(int v, int tl, int tr, int l, int r) { if(l > r) return -1; if(l == tl && r == tr) { return segans[v]; } int tm = (tl + tr) / 2; int left = getans(2 * v, tl, tm, l, min(r, tm)), right = getans(2 * v + 1, tm + 1, tr, max(l, tm + 1), r); if(left == -1) return right; if(right == -1) return left; return lca(left, right); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, m, q; cin >> n >> m >> q; for(int i = 1; i <= n - 1; i++) { int f, s; cin >> f >> s; adj[f].push_back(s); adj[s].push_back(f); } dfs(1, -1, 0); buildlca(1, 0, euler.size() - 1); for(int i = 0; i < m; i++) cin >> seq[i]; buildans(1, 0, m - 1); //cout << in[2] << " " << in[3] << " " << height[2] << " " << height[3] << " " << lca(2, 2) << "\n"; while(q--) { int type; cin >> type; if(type == 1) { int pos, val; cin >> pos >> val; pos--; seq[pos] = val; //updateans(1, 0, m - 1, pos, val); } else { int l, r, v; cin >> l >> r >> v; l--; r--; int curr = 0; int last = l; bool valid = false; for(int i = l; i <= r; i++) { if(!(in[v] <= in[seq[i]] && in[seq[i]] <= out[v])) { curr = 0; last = i + 1; continue; } if(curr == 0) curr = seq[i]; else curr = lca(curr, seq[i]); if(curr == v) { cout << last + 1 << " " << i + 1 << "\n"; valid = true; break; } } if(!valid) cout << "-1 -1\n"; } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...