Submission #1150622

#TimeUsernameProblemLanguageResultExecution timeMemory
1150622polarityRegions (IOI09_regions)C++20
100 / 100
2284 ms36024 KiB
/** * Solution by 1egend (polarity.sh) * Date: 2025-02-15 * Contest: IOI 2009 * Problem: regions **/ #include <bits/stdc++.h> using namespace std; using ull = unsigned long long; using ll = long long; using vi = vector<int>; using vl = vector<ll>; using pii = pair<int, int>; #define pb push_back #define rep(i, a, b) for(int i = (a); i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() const int MAX_N = 1e5 + 1; const ll MOD = 1e9 + 7; /** * ALGORITHM: Euler Tour * PURPOSE: Flattens a tree so that each range contains any subtree range * CONSTRAINT: Graph must be a tree * TIME: O(V) */ vector<pii> eulerTour(int n, vector<vector<int>> &adj){ vector<pii> ans(n); int i = -1; function<void(int, int)> tour; tour = [&](int node, int parent){ ans[node].first = ++i; for (int x : adj[node]){ if (x != parent){ tour(x, node); } } ans[node].second = i; }; // root at 0 tour(0, 0); return ans; } void solve(){ int n, r, q; cin >> n >> r >> q; int rt = sqrt(n); vector<vi> adj(n); vi region(n); rep(i, 0, n){ if (i == 0){ cin >> region[0]; region[0]--; continue; } int s; cin >> s; --s; adj[i].pb(s); adj[s].pb(i); cin >> region[i]; region[i]--; } vector<pii> tree = eulerTour(n, adj); vector<vi> regions(r); vi count(r, 0); vi rend(n); vi arr(n); rep(i, 0, n){ count[region[i]]++; regions[region[i]].pb(tree[i].first); arr[tree[i].first] = region[i]; rend[tree[i].first] = tree[i].second; } vi idx(r); int k = 0; rep(i, 0, r){ sort(all(regions[i])); if (count[i] > rt){ idx[i] = k; k++; } } vi curr(k, 0); vector<vector<int>> ans(k, vector<int>(r, 0)); using T = pii; priority_queue<T, vector<T>, greater<T>> pq; rep(i, 0, n){ int a = arr[i]; if (count[a] > rt){ pq.push(pii{rend[i], idx[a]}); curr[idx[a]]++; } while(!pq.empty() && pq.top().first < i){ curr[pq.top().second]--; pq.pop(); } rep(j, 0, k){ ans[j][a] += curr[j]; } } rep(i, 0, q){ int r1, r2; cin >> r1 >> r2; --r1; --r2; if (count[r1] > rt){ cout << ans[idx[r1]][r2] << endl; continue; } int a = 0; rep(j, 0, regions[r1].size()){ int s = regions[r1][j]; int e = rend[s]; a += upper_bound(all(regions[r2]), e) - upper_bound(all(regions[r2]), s); } cout << a << endl; } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...