제출 #1183677

#제출 시각아이디문제언어결과실행 시간메모리
1183677sardor_salimovTourism (JOI23_tourism)C++17
28 / 100
5094 ms19728 KiB
#include <bits/stdc++.h> #define ar array #define all(x) x.begin(), x.end() using namespace std; typedef long long ll; const int N = 1e5 + 5, B = 200, lg = 17; vector <int> g[N]; int st[lg][N], bit[N], d[N], n, m, q; int c[N], tin[N], tout[N], tim = 0; void dfs(int x, int par) { tin[x] = ++tim; st[0][x] = par; d[x] = d[par] + 1; for (int i = 1; i < lg; i++) st[i][x] = st[i - 1][st[i - 1][x]]; for (int &y : g[x]) { if (y != par) { dfs(y, x); } } tout[x] = tim; } void upd(int i, int qx) { while (i <= n) { bit[i] += qx; i |= (i + 1); } } int get(int i) { int ans = 0; while (i >= 0) { ans += bit[i]; i = (i & (i + 1)) - 1; } return ans; } int get(int l, int r) { return get(r) - get(l - 1); } int lca = -1, cnt[N], sm = 0, ans = 0; multiset <int> mst; void add(int x) { mst.insert(x); if (lca == -1) lca = x, ans++; if (cnt[x] == 0) { int sb = get(tin[x], tout[x]), nsb = sm - sb; if (min(sb, nsb) == 0) { if (nsb == 0) { ans += d[lca] - d[x]; lca = x; } else { int b = 16, y = x, res = 1; while (b >= 0) { int ty = st[b][y]; if (get(tin[ty], tout[ty]) == 0) y = ty, res += (1 << b); b--; } y = st[0][y]; if (d[lca] > d[y]) { res += d[lca] - d[y]; lca = y; } ans += res; } } } cnt[x]++, sm++, upd(tin[x], 1); } int nlca() { int y = *mst.begin(), b = 16; if (sm == get(tin[y], tout[y])) return y; while (b >= 0) { int ty = st[b][y]; if (sm - get(tin[ty], tout[ty]) > 0) y = ty; b--; } y = st[0][y]; return y; } void rem(int x) { mst.erase(mst.find(x)); cnt[x]--, sm--, upd(tin[x], -1); if (cnt[x] == 0) { int sb = get(tin[x], tout[x]), nsb = sm - sb; if (nsb > 0 && sb > 0) return; if (sb == 0) { int b = 16, y = x, res = 1; while (b >= 0) { int ty = st[b][y]; if (get(tin[ty], tout[ty]) == 0) y = ty, res += (1 << b); b--; } y = st[0][y]; if (sm - get(tin[y], tout[y]) + cnt[y] == 0) { int sv = y; y = nlca(); res += d[y] - d[sv]; lca = y; } ans -= res; } else { int y = nlca(); ans -= d[y] - d[lca]; lca = y; } } } int tl = 1, tr = 0; void correct(int l, int r) { while (tr < r) add(c[++tr]); while (l < tl) add(c[--tl]); while (r < tr) rem(c[tr--]); while (tl < l) rem(c[tl++]); } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m >> q; for (int i = 2; i <= n; i++) { int u, v; cin >> u >> v; g[u].emplace_back(v); g[v].emplace_back(u); } for (int i = 1; i <= m; i++) cin >> c[i]; dfs(1, 0); tout[0] = n; vector <ar <int, 3>> query(q); vector <int> res(q); for (int i = 0; i < q; i++) cin >> query[i][0] >> query[i][1], query[i][2] = i; sort(all(query), [] (const ar <int, 3> &a, const ar <int, 3> &b) { if (a[0] / B == b[0] / B) return a[1] < b[1]; return a[0] / B < b[0] / B; }); for (auto now : query) { correct(now[0], now[1]); res[now[2]] = ans; } for (int i : res) 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...