Submission #1271335

#TimeUsernameProblemLanguageResultExecution timeMemory
1271335MateiKing80Tourism (JOI23_tourism)C++20
100 / 100
877 ms30848 KiB
#include <bits/stdc++.h> using namespace std; const int N = 100005; vector<int> vec[N]; int sz[N], heavyHead[N], heavyOrd[N], posHeavy[N], depth[N], lift[20][N], timer = 0, tin[N], tout[N]; bool isAncestor(int u, int v) { return u == 0 || (tin[u] <= tin[v] && tout[v] <= tout[u]); } int lca(int u, int v) { if (depth[u] > depth[v]) swap(u, v); for (int bit = 19; bit >= 0; bit --) if (depth[lift[bit][v]] >= depth[u]) v = lift[bit][v]; if (u == v) return u; for (int bit = 19; bit >= 0; bit --) if (lift[bit][v] != lift[bit][u]) { v = lift[bit][v]; u = lift[bit][u]; } return lift[0][v]; } struct ura { int l, r, time; bool operator < (const ura &oth) const { return l < oth.l; } }; int aib[N]; inline int lsb(int x) { return x & -x; } void update(int pos, int val) { while (pos < N) { aib[pos] += val; pos += lsb(pos); } } int query(int pos) { int ans = 0; while (pos) { ans += aib[pos]; pos -= lsb(pos); } return ans; } set<ura> s; void updateInterval(int l, int r, int time) { while (1) { auto it = s.lower_bound({l, r, time}); if (it == s.end() || (*it).l > r) { if (it == s.begin()) break; it --; if ((*it).r < l) break; } auto x = *it; update(x.time, -(x.r - x.l + 1)); s.erase(x); if (x.l < l) { update(x.time, l - x.l); s.insert({x.l, l - 1, x.time}); } if (x.r > r) { update(x.time, x.r - r); s.insert({r + 1, x.r, x.time}); } } update(time, r - l + 1); s.insert({l, r, time}); } void updateHeavy(int u, int v, int time) { int x = lca(u, v); for (int skib = 0; skib < 2; skib ++) { swap(u, v); int nu = u; while (!isAncestor(u, v)) { updateInterval(max(posHeavy[heavyHead[u]], posHeavy[x] + 1), posHeavy[u], time); u = lift[0][heavyHead[u]]; } u = nu; } } void dfsSz(int nod, int papa) { depth[nod] = 1 + depth[papa]; lift[0][nod] = papa; for (int i = 1; i < 20; i ++) lift[i][nod] = lift[i - 1][lift[i - 1][nod]]; sz[nod] = 1; for (auto i : vec[nod]) { if (i == papa) continue; dfsSz(i, nod); sz[nod] += sz[i]; } } void dfsHeavy(int nod, int papa, int value) { heavyHead[nod] = value; heavyOrd[++timer] = nod; tin[nod] = timer; for (int i = 0; i < (int)vec[nod].size(); i ++) if (vec[nod][i] == papa) swap(vec[nod][i], vec[nod][vec[nod].size() - 1]); for (int i = 1; i < (int)vec[nod].size(); i ++) { if (vec[nod][i] == papa) continue; if (sz[vec[nod][0]] < sz[vec[nod][i]]) swap(vec[nod][i], vec[nod][0]); } if (vec[nod].size() && vec[nod][0] != papa) dfsHeavy(vec[nod][0], nod, heavyHead[nod]); for (int i = 1; i < (int)vec[nod].size(); i ++) if (vec[nod][i] != papa) dfsHeavy(vec[nod][i], nod, vec[nod][i]); tout[nod] = timer; } signed main() { int n, m, q; cin >> n >> m >> q; for (int i = 1; i < n; i ++) { int u, v; cin >> u >> v; vec[u].push_back(v); vec[v].push_back(u); } dfsSz(1, 0); dfsHeavy(1, 0, 1); for (int i = 1; i <= n; i ++) posHeavy[heavyOrd[i]] = i; vector<int> v(m + 1); for (int i = 1; i <= m; i ++) cin >> v[i]; vector<vector<int>> qrs(m + 1); vector<pair<int, int>> qq(q); vector<int> ans(q); for (int i = 0; i < q; i ++) { int l, r; cin >> l >> r; qq[i] = {l, r}; qrs[r].push_back(i); if (l == 1 && r == 1) ans[i] = 1; } for (int i = 2; i <= m; i ++) { updateHeavy(v[i - 1], v[i], i - 1); for (auto j : qrs[i]) ans[j] = query(i) - query(qq[j].first - 1) + 1; } for (auto &i : ans) cout << i << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...