제출 #1124558

#제출 시각아이디문제언어결과실행 시간메모리
1124558macneilTourism (JOI23_tourism)C++20
0 / 100
224 ms22904 KiB
#include <iostream> #include <vector> #include <cmath> #include <algorithm> #include <string> #include <bitset> #include <iterator> #include <iomanip> #include <map> #include <set> #include <unordered_map> #include <unordered_set> #include <ctime> #include <deque> #include <queue> #include <stack> #include <random> #include <cassert> using namespace std; #define int long long #define all(a) a.begin(), a.end() #define rall(a) a.rbegin(), a.rend() typedef long long ll; typedef long double ld; struct SegTree { vector<int> szs; vector<pair<int, int>> tr; vector<int> lol; int sz; SegTree(){} void build(int n) { sz = (1 << ((int)log2(n))) * 2; lol.resize(2 * sz, -1); tr.resize(sz * 2, {1e9, 1e9}); szs.resize(sz * 2); for (int i = 0; i < n; ++i) szs[sz - 1 + i] = 1; for (int i = sz - 2; i >= 0; --i) szs[i] = szs[i * 2 + 1] + szs[i * 2 + 2]; } void push(int v) { if (lol[v] == -1) return; tr[v] = {lol[v], lol[v]}; if (2 * v + 1 < 2 * sz) { lol[2 * v + 1] = lol[v]; lol[2 * v + 2] = lol[v]; } lol[v] = -1; } pair<int, int> merge(pair<int, int> a, pair<int, int> b) { return {min(a.first, b.first), max(a.second, b.second)}; } void update(int v, int l, int r, int ql, int qr, int x) { push(v); if (ql >= r || qr <= l) return; if (l >= ql && r <= qr) { lol[v] = x; push(v); return; } int m = (l + r) / 2; update(2 * v + 1, l, m, ql, qr, x); update(2 * v + 2, m, r, ql, qr, x); tr[v] = merge(tr[2 * v + 1], tr[2 * v + 2]); } void update(int l, int r, int x) { update(0, 0, sz, l, r, x); } int get(int v, int l, int r, int x) { push(v); if (tr[v].first >= x) return 0; if (tr[v].second < x) return r - l; int m = (l + r) / 2; return get(v * 2 + 1, l, m, x) + get(v * 2 + 2, m, r, x); } int get(int x) { return get(0, 0, sz, x); } }; vector<int> sz, upto, tin, tout, ord, backord; vector<vector<int>> p, gr; SegTree lol; int timer = 0; void dfssize(int v, int pr) { p[0][v] = pr; for (int i = 1; i < 20; ++i) p[i][v] = p[i - 1][p[i - 1][v]]; tin[v] = timer++; sz[v] = 1; for (auto e : gr[v]) { if (e == pr) continue; dfssize(e, v); sz[v] += sz[e]; } tout[v] = timer++; } void dfsreorder(int v, int pr) { backord[v] = ord.size(); ord.push_back(v); if (upto[v] == -1) upto[v] = v; if (gr[v].size() == 1 && pr != -1) return; if (gr[v][0] == pr) swap(gr[v][0], gr[v][1]); for (auto &e : gr[v]) { if (e == pr) continue; if (sz[e] > sz[gr[v][0]]) swap(e, gr[v][0]); } upto[gr[v][0]] = upto[v]; for (auto e : gr[v]) { if (e == pr) continue; dfsreorder(e, v); } } bool isanc(int a, int b) { return tin[a] <= tin[b] && tout[a] >= tout[b]; } int lca(int a, int b) { if (isanc(a, b)) return a; if (isanc(b, a)) return b; for (int i = 19; i >= 0; --i) { if (!isanc(p[i][a], b)) a = p[i][a]; } return p[0][a]; } void update(int a, int b, int ind) { int c = lca(a, b); while (a != c) { int t = upto[a]; if (isanc(t, c)) t = c; lol.update(backord[t], backord[a] + 1, ind); if (t == c) break; a = p[0][t]; } while (b != c) { int t = upto[b]; if (isanc(t, c)) t = c; lol.update(backord[t], backord[b] + 1, ind); if (t == c) break; b = p[0][t]; } } int get(int x) { return lol.get(x); } void solve() { int n, m, q; cin >> n >> m >> q; upto.resize(n, -1); sz.resize(n); tin.resize(n); tout.resize(n); backord.resize(n); p.resize(20, vector<int>(n)); gr.resize(n); lol.build(n); for (int i = 0; i < n - 1; ++i) { int a, b; cin >> a >> b; --a; --b; gr[a].push_back(b); gr[b].push_back(a); } dfssize(0, 0); dfsreorder(0, -1); vector<int> lolkek(m); for (int i = 0; i < m; ++i) { cin >> lolkek[i]; lolkek[i]--; } vector<int> ans(q); vector<vector<pair<int, int>>> qs(n); for (int i = 0; i < q; ++i) { int l, r; cin >> l >> r; if (l == r) { ans[i] = 1; continue; } qs[l - 1].push_back({r, i}); } for (int i = m - 2; i >= 0; --i) { update(lolkek[i], lolkek[i + 1], i + 1); for (auto e : qs[i]) { ans[e.second] = get(e.first); } } for (auto e : ans) cout << e << '\n'; } signed main() { int tc = 1; #ifdef LOCAL freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #else ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #endif // int g; cin >> g; // cin >> tc; for (int t = 1; t <= tc; t++) { // cout << "Case #" << t << ": "; 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...