제출 #1162397

#제출 시각아이디문제언어결과실행 시간메모리
1162397nh0902Regions (IOI09_regions)C++20
100 / 100
3750 ms118168 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long const int N = 200005; const int R = 25005; const long long inf = 1e13; const long long mod = 1e9 + 7; int n, r, m, q; int h[N]; int cnt_r[R]; vector<int> g[N]; vector<int> ans; vector<int> ans_pos[R], ans_pos_rv[R]; vector<pair<int, int>> query_down[R], query_up[R]; int cur_cnt[R]; int sz[N]; void predfs(int u) { sz[u] = 1; for (int v : g[u]) { predfs(v); sz[u] += sz[v]; } } void update(int u, int val) { cur_cnt[h[u]] += val; for (int v : g[u]) update(v, val); } void dfs(int u) { if (sz[u] == 1) { cur_cnt[h[u]] ++; return; } int b = 0; for (int v : g[u]) { if (b == 0 || sz[b] < sz[v]) b = v; } for (int v : g[u]) if (v != b) { dfs(v); update(v, - 1); } dfs(b); for (int v : g[u]) if (v != b) { update(v, 1); } /* cout << u << "\n"; for (int i = 1; i <= r; i ++) { cout << i << " : " << cur_cnt[i] << "\n"; } cout << "\n"; */ for (pair<int, int> x : query_down[h[u]]) { ans[x.second] += cur_cnt[x.first]; } cur_cnt[h[u]] ++; } void dfs2(int u) { for (pair<int, int> x : query_up[h[u]]) { ans[x.second] += cur_cnt[x.first]; } cur_cnt[h[u]] ++; for (int v : g[u]) dfs2(v); cur_cnt[h[u]] --; } vector<int> pos_r[R]; int be[N], en[N]; int cur; void euler(int u) { cur ++; be[u] = cur; for (int v : g[u]) euler(v); en[u] = cur; } int bit[N]; int get(int p) { int idx = p, ans = 0; while (idx > 0) { ans += bit[idx]; idx -= (idx & (-idx)); } return ans; } void upd(int u, int v) { int idx = u; while (idx <= n) { bit[idx] += v; idx += (idx & (-idx)); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); // Use standard input to read from "paint.in" //freopen("promote.in", "r", stdin); // Use standard output to write to "paint.out" //freopen("promote.out", "w", stdout); cin >> n >> r >> q; m = sqrt(n); //cout << m << "\n"; cin >> h[1]; cnt_r[h[1]] ++; pos_r[h[1]].push_back(1); int x; for (int i = 2; i <= n; i ++) { cin >> x >> h[i]; g[x].push_back(i); //cout << x << " - " << i << "\n"; cnt_r[h[i]] ++; pos_r[h[i]].push_back(i); } int query_id = - 1; for (int i = 1; i <= r; i ++) { if (cnt_r[i] < m) continue; for (int j = 1; j <= r; j ++) { query_id ++; ans.push_back(0); ans_pos[i].push_back(query_id); query_up[j].push_back({i, query_id}); query_id ++; ans.push_back(0); ans_pos_rv[i].push_back(query_id); query_down[j].push_back({i, query_id}); } } predfs(1); dfs(1); memset(cur_cnt, 0, sizeof cur_cnt); dfs2(1); euler(1); int u, v; while (q --) { cin >> u >> v; if (cnt_r[u] >= m) { cout << ans[ans_pos[u][v - 1]] << endl; } else if (cnt_r[v] >= m) { cout << ans[ans_pos_rv[v][u - 1]] << endl; } else { for (int x : pos_r[v]) { upd(be[x], 1); } int ret = 0; for (int x : pos_r[u]) { ret += get(en[x]) - get(be[x] - 1); } if (u == v) { ret -= pos_r[u].size(); } cout << ret << endl; for (int x : pos_r[v]) { upd(be[x], - 1); } } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...