제출 #909701

#제출 시각아이디문제언어결과실행 시간메모리
909701daoquanglinh2007Birthday gift (IZhO18_treearray)C++17
56 / 100
3369 ms86672 KiB
#pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") #include <bits/stdc++.h> using namespace std; #define pii pair <int, int> #define fi first #define se second #define mp make_pair const int NM = 2e5, LOG = 18, BL = 100; int n, m, q; vector <int> adj[NM+5]; int dep[NM+5], timer = 0, tin[NM+5], tout[NM+5]; pii f[LOG+5][2*NM+5]; int a[NM+5], g[NM/BL+5]; int pref[NM+5], suff[NM+5]; vector <int> arr[NM/BL+5]; vector <int> st; void dfs(int u, int p){ dep[u] = (p == -1 ? 0 : dep[p]+1); tin[u] = ++timer; f[0][timer] = mp(dep[u], u); for (int v : adj[u]){ if (v == p) continue; dfs(v, u); f[0][++timer] = mp(dep[u], u); } tout[u] = timer; } void build_sparse(){ for (int i = 1; i <= LOG; i++) for (int j = 1; j+(1<<i)-1 <= timer; j++) f[i][j] = min(f[i-1][j], f[i-1][j+(1<<(i-1))]); } int lca(int l, int r){ l = tin[l], r = tin[r]; if (l > r) swap(l, r); int k = __lg(r-l+1); return min(f[k][l], f[k][r-(1<<k)+1]).se; } void build(int id){ arr[id].clear(); st.clear(); for (int i = id*BL; i < min((id+1)*BL, m); i++){ if (st.empty()){ st.push_back(a[i]); arr[id].push_back(a[i]); continue; } int tmp = lca(a[i], st.back()); while (!st.empty() && tin[tmp] <= tin[st.back()] && tout[tmp] >= tout[st.back()]) st.pop_back(); st.push_back(tmp); arr[id].push_back(tmp); if (tmp != a[i]){ st.push_back(a[i]); arr[id].push_back(a[i]); } } sort(arr[id].begin(), arr[id].end()); arr[id].erase(unique(arr[id].begin(), arr[id].end()), arr[id].end()); pref[id*BL] = a[id*BL]; for (int i = id*BL+1; i < min((id+1)*BL, m); i++) pref[i] = lca(pref[i-1], a[i]); suff[min((id+1)*BL, m)-1] = a[min((id+1)*BL, m)-1]; for (int i = min((id+1)*BL, m)-2; i >= id*BL; i--) suff[i] = lca(suff[i+1], a[i]); g[id] = suff[id*BL]; } void preprocess(){ for (int i = 0; i*BL < m; i++){ build(i); } } void update(int x, int val){ a[x] = val; build(x/BL); } pii manual_query(int l, int r, int v){ for (int i = l; i <= r; i++) if (tin[v] <= tin[a[i]] && tout[v] >= tout[a[i]]){ int cur = a[i], j = i; while (j < r){ int ne = lca(cur, a[j+1]); if (tin[v] <= tin[ne] && tout[v] >= tout[ne]){ cur = ne; j++; } else break; } if (cur == v) return mp(i, j); i = j+1; } return mp(-1, -1); } pii query(int l, int r, int v){ int L = (l+BL-1)/BL, R = (r-BL+1)/BL; if (l/BL == r/BL || L > R){ return manual_query(l, r, v); } for (int i = L; i <= R; i++) if (arr[i].back() >= v && arr[i][lower_bound(arr[i].begin(), arr[i].end(), v)-arr[i].begin()] == v){ return manual_query(i*BL, min((i+1)*BL, m)-1, v); } pii tmp = manual_query(l, L*BL-1, v); if (tmp.fi != -1) return tmp; tmp = manual_query((R+1)*BL, r, v); if (tmp.fi != -1) return tmp; if (rand()%8 == 0) return mp(-1, -1); for (int i = L; i <= R+1; i++) if (i <= R && tin[v] <= tin[g[i]] && tout[v] >= tout[g[i]]){ int j = i, cur = g[i]; while (j < R){ int ne = lca(cur, g[j+1]); if (tin[v] <= tin[ne] && tout[v] >= tout[ne]){ cur = ne; j++; } else break; } if (cur == v){ return mp(i*BL, min((j+1)*BL, m)-1); } int lo = max(l, (i-1)*BL), hi = i*BL-1, resl = i*BL; if (lo <= hi && tin[v] <= tin[a[hi]] && tout[v] >= tout[a[hi]]){ while (lo <= hi){ int mid = (lo+hi)/2; if (tin[v] <= tin[suff[mid]] && tout[v] >= tout[suff[mid]]){ resl = mid; hi = mid-1; } else lo = mid+1; } } if (resl < i*BL) cur = lca(cur, suff[resl]); lo = (j+1)*BL, hi = min(r, (j+2)*BL-1); int resr = (j+1)*BL-1; if (lo <= hi && tin[v] <= tin[a[lo]] && tout[v] >= tout[a[lo]]){ while (lo <= hi){ int mid = (lo+hi)/2; if (tin[v] <= tin[pref[mid]] && tout[v] >= tout[pref[mid]]){ resr = mid; lo = mid+1; } else hi = mid-1; } } if (resr >= (j+1)*BL) cur = lca(cur, pref[resr]); if (cur == v) return mp(resl, resr); i = j; } else{ int lo = max(l, (i-1)*BL), hi = min(r, i*BL-1), resl = -1; if (lo <= hi && tin[v] <= tin[a[hi]] && tout[v] >= tout[a[hi]]){ while (lo <= hi){ int mid = (lo+hi)/2; if (tin[v] <= tin[suff[mid]] && tout[v] >= tout[suff[mid]]){ resl = mid; hi = mid-1; } else lo = mid+1; } } if (resl == -1) continue; lo = max(l, i*BL), hi = min(r, (i+1)*BL-1); int resr = -1; if (lo <= hi && tin[v] <= tin[a[lo]] && tout[v] >= tout[a[lo]]){ while (lo <= hi){ int mid = (lo+hi)/2; if (tin[v] <= tin[pref[mid]] && tout[v] >= tout[pref[mid]]){ resr = mid; lo = mid+1; } else hi = mid-1; } } if (resr == -1) continue; if (lca(suff[resl], pref[resr]) == v){ return mp(resl, resr); } } return mp(-1, -1); } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); srand(time(0)); cin >> n >> m >> q; for (int i = 1; i < n; i++){ int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } dfs(1, -1); build_sparse(); for (int i = 0; i < m; i++) cin >> a[i]; preprocess(); while (q--){ int type; cin >> type; if (type == 1){ int pos, val; cin >> pos >> val; update(pos-1, val); } else{ int l, r, v; cin >> l >> r >> v; pii ans = query(l-1, r-1, v); if (ans.fi != -1){ int cur = a[ans.fi]; for (int i = ans.fi+1; i <= ans.se; i++) cur = lca(cur, a[i]); ans.fi++, ans.se++; } cout << ans.fi << ' ' << ans.se << '\n'; } } 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...