Submission #1307252

#TimeUsernameProblemLanguageResultExecution timeMemory
1307252buzdiRegions (IOI09_regions)C++17
90 / 100
8023 ms35480 KiB
#include <bits/stdc++.h> #define ll long long using namespace std; const int NMAX = 2e5; const int RMAX = 25000; const int BLOCK = 500; int n, r, q, t; int reg[NMAX + 1]; int freq[RMAX + 1]; int in[NMAX + 1], out[NMAX + 1]; int sp[NMAX + 1]; vector<int> g[NMAX + 1], in_reg[RMAX + 1], out_reg[RMAX + 1], nodes_reg[RMAX + 1]; void DFS(int node, int dad = 0) { in[node] = ++t; in_reg[reg[node]].push_back(in[node]); for(int next_node : g[node]) { if(next_node != dad) { DFS(next_node, node); } } out[node] = t; out_reg[reg[node]].push_back(out[node]); } int lower_bound_in(vector<int>& a, vector<int>& b) { int sz_a = a.size(), sz_b = b.size(), i = 0, j = 0, answer = 0; while(i < sz_a && j < sz_b) { if(a[i] <= b[j]) { answer += sz_b - j; i++; } else { j++; } } return answer; } int upper_bound_out(vector<int>& a, vector<int>& b) { int sz_a = a.size(), sz_b = b.size(), i = 0, j = 0, answer = 0; while(i < sz_a && j < sz_b) { if(a[i] < b[j]) { answer += sz_b - j; i++; } else { j++; } } return answer; } int query_both_small(int r1, int r2) { return lower_bound_in(in_reg[r1], in_reg[r2]) - upper_bound_out(out_reg[r1], in_reg[r2]); } int query_small(int r1, int r2) { int answer = 0; for(int node : nodes_reg[r1]) { auto itr = upper_bound(in_reg[r2].begin(), in_reg[r2].end(), out[node]); auto itl = lower_bound(in_reg[r2].begin(), in_reg[r2].end(), in[node]); answer += itr - itl; } return answer; } int query_big(int r1, int r2) { /// Activate r2 /// Query r1 fill(sp + 1, sp + n + 1, 0); for(int node : nodes_reg[r2]) { sp[in[node]]++; } for(int i = 1; i <= n; i++) { sp[i] += sp[i - 1]; } int answer = 0; for(int node : nodes_reg[r1]) { answer += sp[out[node]] - sp[in[node] - 1]; } return answer; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> r >> q; cin >> reg[1]; for(int i = 2; i <= n; i++) { int x; cin >> x >> reg[i]; g[x].push_back(i); g[i].push_back(x); } for(int i = 1; i <= n; i++) { freq[reg[i]]++; nodes_reg[reg[i]].push_back(i); } DFS(1); while(q--) { int r1, r2; cin >> r1 >> r2; if(freq[r1] <= BLOCK && freq[r2] <= BLOCK) { cout << query_both_small(r1, r2) << endl; } else if(freq[r1] <= BLOCK) { cout << query_small(r1, r2) << endl; } else { cout << query_big(r1, r2) << endl; } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...