Submission #957158

#TimeUsernameProblemLanguageResultExecution timeMemory
957158ZHIRDILBILDIZTourism (JOI23_tourism)C++14
100 / 100
589 ms38860 KiB
#include<bits/stdc++.h> #define fi first #define se second #define ll long long #define pii pair<int, int> using namespace std; const int N = (1 << 17); int c[N]; int sum[N << 1 ^ 1]; vector<int> gr[N]; vector<pii> qr[N]; ///segment_tree begin void upd_point_seg_tree (int ind, int vall) { ind += N - 1; sum[ind] += vall; ind >>= 1; while (ind) { sum[ind] = sum[ind << 1] + sum[ind << 1 ^ 1]; ind >>= 1; } } int get_sum(int l1, int r1, int l = 1, int r = N, int v = 1) { if (l > r1 || r < l1) return 0; if (l1 <= l && r <= r1) return sum[v]; int mid = (l + r) >> 1; return get_sum(l1, r1, l, mid, v << 1) + get_sum(l1, r1, mid + 1, r, v << 1 ^ 1); } ///segment_tree end ///build_compose begin int pos[N]; int pr[N]; int big[N]; int head[N]; int tin[N]; int tout[N]; int timer; int lc[N][20]; vector<int> tr; bool upper(int u, int v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; } int pre_calc (int city = 1, int last = 0) { tin[city] = ++timer; int cnt = 1; pii mx = {0, 0}; for (int i : gr[city]) { if (i == last) continue; int w = pre_calc(i, city); mx = max(mx, {w, i}); cnt += w; } tout[city] = ++timer; big[city] = mx.se; return cnt; } void dfs (int city = 1, int last = 0, int h = 1) { pr[city] = last; lc[city][0] = last; for (int i = 1; i < 20; ++i) lc[city][i] = lc[lc[city][i - 1]][i - 1]; head[city] = h; pos[city] = tr.size(); tr.push_back(city); if (big[city]) dfs(big[city], city, h); for (int i : gr[city]) { if (i == last || i == big[city]) continue; dfs(i, city, i); } } ///build_compose end ///query and update on decompose begin int color[2 * N + 1]; bool have[2 * N + 1]; void tractor (int v) { have[v] = (color[v] > 0); if (v < N && (have[v << 1] || have[v << 1 ^ 1])) have[v] = 1; } void push (int v) { if (!color[v] || v >= N) return; int x = color[v]; color[v] = 0; color[v << 1] = x; color[v << 1 ^ 1] = x; tractor(v << 1); tractor(v << 1 ^ 1); } void set_color (int l, int r, int v, int x) { if (color[v]) upd_point_seg_tree(color[v], -(r - l + 1)); color[v] = x; if (color[v]) upd_point_seg_tree(color[v], (r - l + 1)); tractor(v); } void mega_clear (int l, int r, int v) { set_color (l, r, v, 0); if (!have[v]) return; int mid = (l + r) >> 1; mega_clear (l, mid, v << 1); mega_clear (mid + 1, r, v << 1 ^ 1); have[v] = 0; } void update (int l1, int r1, int x, int l = 0, int r = N - 1, int v = 1) { if (l > r1 || r < l1) return; if (l1 <= l && r <= r1) { mega_clear(l, r, v); set_color(l, r, v, x); return; } push(v); int mid = (l + r) >> 1; update(l1, r1, x, l, mid, v << 1); update(l1, r1, x, mid + 1, r, v << 1 ^ 1); tractor(v); } int get_lca(int u, int v) { if (upper(u, v)) return u; if (upper(v, u)) return v; for (int i = 19; i >= 0; --i) if (lc[u][i] && !upper(lc[u][i], v)) u = lc[u][i]; return pr[u]; } void update_on_path (int u, int v, int x) { int lc = get_lca(u, v); // cout << "update_on_path " << u << ' ' << v << ' ' << lc << ' ' << x << '\n'; while (u != pr[lc]) { if (!upper(head[u], lc)) { update(pos[head[u]], pos[u], x); // cout << "sum1 = " << pos[head[u]] << ' ' << pos[u] << ' ' << get_sum(4, 6) << '\n'; u = pr[head[u]]; } else { update(pos[lc], pos[u], x); // cout << "sum2 = " << pos[lc] << ' ' << pos[u] << ' ' << get_sum(4, 6) << '\n'; u = pr[lc]; } } while (v != pr[lc]) if (!upper(head[v], lc)) { update(pos[head[v]], pos[v], x); // cout << "sum3 = " << pos[head[v]] << ' ' << pos[v] << ' ' << get_sum(4, 6) << '\n'; v = pr[head[v]]; } else { update(pos[lc], pos[v], x); // cout << "sum4 = " << pos[lc] << ' ' << pos[v] << ' ' << get_sum(4, 6) << '\n'; v = pr[lc]; } } ///query and update on decompose end signed main () { ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0); int n, m, q; cin >> n >> m >> q; for (int i = 1; i < n; ++i) { int u, v; cin >> u >> v; gr[u].push_back(v); gr[v].push_back(u); } for (int i = 1; i <= m; ++i) cin >> c[i]; int ans[q + 1] = {}; for (int i = 1; i <= q; ++i) { int l, r; cin >> l >> r; if (l == r) { ans[i] = 1; continue; } qr[r].push_back({l, i}); } pre_calc(); dfs(); for (int i = 2; i <= m; ++i) { update_on_path (c[i - 1], c[i], i - 1); // cout << "after update_on_path " << c[i - 1] << ' ' << c[i] << ' ' << i - 1 << " " << get_sum(4, 6) << '\n'; // cout << "_______________________________________________\n"; for (auto j : qr[i]) ans[j.se] = get_sum(j.fi, i); } for (int i = 1; i <= q; ++i) cout << ans[i] << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...