Submission #1083608

#TimeUsernameProblemLanguageResultExecution timeMemory
1083608Blistering_BarnaclesTourism (JOI23_tourism)C++17
100 / 100
863 ms29012 KiB
//Billions of bilious blue blistering barnacles in a thundering typhoon! //Yesterday is history, tomorrow is a mystery, today is a gift of God, which is why we call it the present. #include<bits/stdc++.h> using namespace std; void solve() { int n, m, q; cin >> n >> m >> q; vector<vector<int>> adj(n + 1); for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; adj[u].push_back(v), adj[v].push_back(u); } vector<int> c(m + 1); for (int i = 1; i <= m; i++) { cin >> c[i]; } vector<vector<pair<int, int>>> qu(m + 1); vector<int> ans(q + 1); for (int i = 1; i <= q; i++) { int l, r; cin >> l >> r; if (l == r) ans[i] = 1; else qu[r].push_back({l, i}); } vector<int> csz(n + 1), top(n + 1), pr(n + 1), nxt(n + 1), sz(n + 1), dep(n + 1), chain(n + 1), num(n + 1); function<void(int, int)> dfs = [&](int v, int par) { pr[v] = par; nxt[v] = 0; sz[v] = 1; for (int u: adj[v]) { if (u == par) continue; dep[u] = dep[v] + 1; dfs(u, v); if (sz[u] > sz[nxt[v]]) nxt[v] = u; sz[v] += sz[u]; } }; dfs(1, 0); int cnt = 1, all = 0; function<void(int, int)> hld = [&](int v, int par) { chain[v] = cnt; num[v] = ++all; if (!csz[cnt]) top[cnt] = v; csz[cnt]++; if (nxt[v]) hld(nxt[v], v); for (int u: adj[v]) { if (u == par || u == nxt[v]) continue; cnt++; hld(u, v); } }; hld(1, 0); set<array<int, 3>> se; se.insert({1, n, 1}); vector<int> bit(m + 1); auto update = [&](int i, int val) { while (i <= m) { bit[i] += val; i += i & -i; } }; update(1, n); auto query = [&](int l, int r) { int ret = 0; while (r > 0) { ret += bit[r]; r -= r & -r; } l--; while (l > 0) { ret -= bit[l]; l -= l & -l; } return ret; }; auto change = [&](int l, int r, int val) { auto cur = se.lower_bound({l, l, 0}); if (cur != se.begin()) cur--; vector<array<int, 3>> add, rem; add.push_back({l, r, val}); while (cur != se.end() && (*cur)[0] <= r) { auto [l1, r1, v1] = *cur; if (r1 < l) { cur++; continue; } rem.push_back(*cur); if (l1 < l) { add.push_back({l1, l - 1, v1}); } if (r1 > r) { add.push_back({r + 1, r1, v1}); } cur++; } for (auto b: rem) { se.erase(b); auto [l1, r1, v1] = b; update(v1, -(r1 - l1 + 1)); } for (auto b: add) { se.insert(b); auto [l1, r1, v1] = b; update(v1, (r1 - l1 + 1)); } }; function<void(int, int, int)> upd = [&](int u, int v, int val) { while (chain[u] != chain[v]) { if (dep[top[chain[u]]] < dep[top[chain[v]]]) swap(u, v); int start = top[chain[u]]; change(num[start], num[u], val); u = pr[start]; } if (dep[u] > dep[v]) swap(u, v); change(num[u], num[v], val); }; for (int i = 1; i <= m; i++) { if (i > 1) { upd(c[i - 1], c[i], i); } for (auto [l, j]: qu[i]) { ans[j] = query(l + 1, i); } } for (int i = 1; i <= q; i++) { cout << ans[i] << "\n"; } } int main() { ios::sync_with_stdio(0), cin.tie(0); int tt = 1; //cin >> tt; while (tt--) { solve(); } }
#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...