Submission #366883

#TimeUsernameProblemLanguageResultExecution timeMemory
366883kostia244Regions (IOI09_regions)C++17
100 / 100
6462 ms41832 KiB
#include<bits/stdc++.h> #define all(x) begin(x), end(x) using namespace std; const int maxn = 2e5 + 5, C = 300; using ll = long long; int n, r, q, tin[maxn], tout[maxn], col[maxn], col_cnt[maxn], heavy_id[maxn], heavy_cnt = 0, timer = 0; vector<int> g[maxn], col_list[maxn]; vector<int> col_tin[maxn], col_tout[maxn]; void dfs(int v) { tin[v] = timer++; for(int i : g[v]) dfs(i); tout[v] = timer; } //A[bottom][top] ll A[maxn/C + 1][maxn/C + 1], par_cols[maxn]; void count_heavy(int v) { if(heavy_id[col[v]] >= 0) { par_cols[heavy_id[col[v]]]++; A[heavy_id[col[v]]][heavy_id[col[v]]]--; for(int i = 0; i < heavy_cnt; i++) A[heavy_id[col[v]]][i] += par_cols[i]; } for(int i : g[v]) { count_heavy(i); } if(heavy_id[col[v]] >= 0) par_cols[heavy_id[col[v]]]--; } void count_light() { for(int i = 0; i < r; i++) { vector<int> &tins = col_tin[i], &touts = col_tout[i]; for(auto v : col_list[i]) tins.push_back(tin[v]), touts.push_back(tout[v]); sort(all(tins)); sort(all(touts)); } } int lower_bound(vector<int> &a, int x) { int as = a.size(), i = -1; for(int z = 1<<18; z>>=1;) i += z*(i+z < as && a[i+z] <= x); return i+1; } ll count_top(int r1, int r2) { ll ans = 0; for(auto i : col_list[r1]) { ans += lower_bound(col_tin[r2], tout[i]-1) - lower_bound(col_tin[r2], tin[i]-1); } return ans; } ll count_bottom(int r1, int r2) { ll ans = 0; //cout << "Uh " << col_list[r2].size() << " v " << col_list[r1].size() << endl; for(auto i : col_list[r2]) { ans += lower_bound(col_tin[r1], tin[i]) - lower_bound(col_tout[r1], tin[i]); //cout << lower_bound(col_tin[r1], tin[i]) << " | " << lower_bound(col_tout[r1], tin[i]) << endl; } return ans; } ll count_linear(int r1, int r2) { if(col_cnt[r1] < col_cnt[r2]) return count_top(r1, r2); return count_bottom(r1, r2); } int main() { cin.tie(0)->sync_with_stdio(0); cin >> n >> r >> q; for(int t, i = 0; i < n; i++) { if(i) cin >> t, t--, g[t].push_back(i); cin >> col[i];col[i]--; col_cnt[col[i]]++; col_list[col[i]].push_back(i); } memset(heavy_id, -1, sizeof heavy_id); dfs(0); for(int i = 0; i < r; i++) if(col_cnt[i] > C) { heavy_id[i] = heavy_cnt++; } count_heavy(0); count_light(); /* for(auto i : col_tin[0]) cout << i << " "; cout << endl; for(auto i : col_tout[0]) cout << i << " "; cout << endl; for(auto i : col_tin[1]) cout << i << " "; cout << endl; for(auto i : col_tout[1]) cout << i << " "; cout << endl; */ for(int r1, r2; q--; cout << endl) { cin >> r1 >> r2; --r1, --r2; if(min(heavy_id[r1], heavy_id[r2]) >= 0) { cout << A[heavy_id[r2]][heavy_id[r1]]; continue; } //cout << r1 << " " << r2 << "uwu" << endl; cout << count_linear(r1, r2); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...