Submission #525645

#TimeUsernameProblemLanguageResultExecution timeMemory
525645Aldas25Regions (IOI09_regions)C++14
100 / 100
3807 ms34348 KiB
#include <bits/stdc++.h> using namespace std; #define FAST_IO ios_base::sync_with_stdio(0); cin.tie(0) #define FOR(i, a, b) for(int i = (a); i <= (b); i++) #define REP(n) FOR(O, 1, (n)) #define pb push_back #define f first #define s second typedef long double ld; typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; typedef vector<pii> vii; //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int MAXN = 250100, MAXK = 20; const ll MOD = 1e9+7; const ll C = 500; const ll c = 500; int n, r, q; int h[MAXN]; int regSz[MAXN]; bool bgReg[MAXN]; vi adj[MAXN]; int regToId[MAXN]; int idToReg[MAXN]; int tin[MAXN], tout[MAXN]; int crT = 0; void dfs (int v, int p = -1) { tin[v] = ++crT; for (int u : adj[v]) { dfs (u, v); } tout[v] = crT; } bool isAnc (int a, int b) { return (tin[a] <= tin[b] && tout[b] <= tout[a]); } vii nodes; vii inReg[MAXN]; ll pref[MAXN]; ll ans[C][25100]; int getUpperBound (int r, int x) { int sz = (int)inReg[r].size(); if (sz == 0) return sz; if (inReg[r][sz-1].f <= x) return sz; int le = 0, ri = sz-1; while (le < ri) { int m = (le+ri)/2; if (inReg[r][m].f > x) ri = m; else le = m+1; } return le; } int main() { FAST_IO; cin >> n >> r >> q; cin >> h[1]; FOR(i, 2, n) { int pr; cin >> pr; adj[pr].pb(i); cin >> h[i]; } FOR(i, 1, n) regSz[h[i]]++; int lstId = 0; FOR(i, 1, r) { bgReg[i] = (regSz[i] > c); if (bgReg[i]) { regToId[i] = ++lstId; idToReg[lstId] = i; } // cout << " i = " << i << " regSz = " << regSz[i] << " bg = " << bgReg[i] << endl; // if (bgReg[i]) cout << " regToId[i]=" << regToId[i] << endl; } dfs(1); FOR(i, 1, n) { nodes.pb({tin[i], i}); inReg[h[i]].pb({tin[i], i}); } sort(nodes.begin(), nodes.end()); FOR(i, 1, r) sort(inReg[i].begin(), inReg[i].end()); FOR(i, 0, C-1) { if (idToReg[i] == 0) continue; int r = idToReg[i]; FOR(j, 0, n) pref[j] = 0; for (auto p : inReg[r]) { int v = p.s; pref[tin[v]]++; pref[tout[v]+1]--; } FOR(j, 1, n) pref[j] += pref[j-1]; FOR(j, 1, n) { int v = nodes[j-1].s; ans[i][h[v]] += pref[j]; } } REP(q) { int r1, r2; cin >> r1 >> r2; if (bgReg[r1]) { cout << ans[regToId[r1]][r2] << endl; } else { ll ats = 0; for (auto p : inReg[r1]) { int v = p.s; int ri = getUpperBound (r2, tout[v]); int le = getUpperBound (r2, tin[v]); ats += max(0, ri-le); } cout << ats << endl; } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...