Submission #539183

#TimeUsernameProblemLanguageResultExecution timeMemory
539183fcwRegions (IOI09_regions)C++17
100 / 100
4119 ms38340 KiB
#include <bits/stdc++.h> #define st first #define nd second using lint = int64_t; constexpr int mod = int(1e9) + 7; constexpr int inf = 0x3f3f3f3f; constexpr int ninf = 0xcfcfcfcf; constexpr lint linf = 0x3f3f3f3f3f3f3f3f; const long double pi = acosl(-1.0); // Returns -1 if a < b, 0 if a = b and 1 if a > b. int cmp_double(double a, double b = 0, double eps = 1e-9) { return a + eps > b ? b + eps > a ? 0 : 1 : -1; } using namespace std; template<class T> struct segtree_range { int H, N; vector<T> ts; segtree_range() {} explicit segtree_range(int N_) { for (H = 0, N = 1; N < N_; ++H, N *= 2) {} ts.resize(2*N); } template<class Q> explicit segtree_range(const vector<Q>& qs) { const int N_ = int(qs.size()); for (H = 1, N = 1; N < N_; ++H, N *= 2) {} ts.resize(2*N); for (int i = 0; i < N_; ++i) at(i) = T(qs[i]); build(); } T& at(int a) { return ts[a + N]; } void build() { for (int a = N; --a; ) merge(a); } inline void push(int a) { ts[a].push(ts[2 * a], ts[2 * a + 1]); } inline void merge(int a) { ts[a].merge(ts[2*a], ts[2*a+1]); } void for_parents_down(int a, int b) { for (int h = H; h; --h) { const int l = (a >> h), r = (b >> h); if (l == r) { if ((l << h) != a || (r << h) != b) push(l); } else { if ((l << h) != a) push(l); if ((r << h) != b) push(r); } } } void for_parents_up(int a, int b) { for (int h = 1; h <= H; ++h) { const int l = (a >> h), r = (b >> h); if (l == r) { if ((l << h) != a || (r << h) != b) merge(l); } else { if ((l << h) != a) merge(l); if ((r << h) != b) merge(r); } } } template<class F, class... Args> void update(int a, int b, F f, Args&&... args) { if (a == b) return; a += N; b += N; for_parents_down(a, b); for (int l = a, r = b; l < r; l /= 2, r /= 2) { if (l & 1) (ts[l++].*f)(args...); if (r & 1) (ts[--r].*f)(args...); } for_parents_up(a, b); } T query(int a, int b) { if (a == b) return T(); a += N; b += N; for_parents_down(a, b); T lhs, rhs, t; for (int l = a, r = b; l < r; l /= 2, r /= 2) { if (l & 1) { t.merge(lhs, ts[l++]); lhs = t; } if (r & 1) { t.merge(ts[--r], rhs); rhs = t; } } t.merge(lhs, rhs); return t; } template<class Op, class E, class F, class... Args> auto query(int a, int b, Op op, E e, F f, Args&&... args) { if (a == b) return e(); a += N; b += N; for_parents_down(a, b); auto lhs = e(), rhs = e(); for (int l = a, r = b; l < r; l /= 2, r /= 2) { if (l & 1) lhs = op(lhs, (ts[l++].*f)(args...)); if (r & 1) rhs = op((ts[--r].*f)(args...), rhs); } return op(lhs, rhs); } // find min i s.t. T::f(args...) returns true in [a, i) from left to right template<class F, class... Args> int find_right(int a, F f, Args &&... args) { assert(0 <= a && a <= N); if ((T().*f)(args...)) return a; if (a == N) return 1 + N; a += N; for (int h = H; h; --h) push(a >> h); for (; ; a /= 2) if (a & 1) { if ((ts[a].*f)(args...)) { for (; a < N; ) { push(a); if (!(ts[a <<= 1].*f)(args...)) ++a; } return a - N + 1; } ++a; if (!(a & (a - 1))) return N + 1; } } // find max i s.t. T::f(args...) returns true in [i, a) from right to left template<class F, class... Args> int find_left(int a, F f, Args &&... args) { assert(0 <= a && a <= N); if ((T().*f)(args...)) return a; if (a == 0) return -1; a += N; for (int h = H; h; --h) push((a - 1) >> h); for (; ; a /= 2) if ((a & 1) || a == 2) { if ((ts[a - 1].*f)(args...)) { for (; a <= N; ) { push(a - 1); if (!(ts[(a <<= 1) - 1].*f)(args...)) --a; } return a - N - 1; } --a; if (!(a & (a - 1))) return -1; } } }; template<typename T>struct seg_node{ T val; seg_node(T n = 0): val(n){} void push(seg_node& l, seg_node& r){ } void merge(const seg_node& l, const seg_node& r){ val = l.val + r.val; } void add(T n){ val += n; } T get_sum(){ return val; } }; int main() { cin.tie(nullptr)->sync_with_stdio(false); //ifstream cin; //cin.open("promote.in"); //ofstream cout; //cout.open("promote.out"); int n, r, q; cin>>n>>r>>q; vector<vector<int>>g(n); vector<int>p(n), h(n); cin>>h[0]; h[0]--; for(int i=1;i<n;i++){ cin>>p[i]>>h[i]; p[i]--, h[i]--; g[p[i]].push_back(i); } vector<vector<int>>reg(r); for(int i=0;i<n;i++) reg[h[i]].push_back(i); int SZ = sqrt(n); vector<vector<int>>prep(r); vector<int>heavy; for(int i=0;i<r;i++){ if((int)reg[i].size() > SZ){ prep[i] = vector<int>(r); heavy.push_back(i); } } vector<int>tin(n), tout(n), cnt(r); vector<vector<int>>v(n); int timer = 0; auto dfs = [&](auto& self, int u, int p)->void{ tin[u] = timer++; v[h[u]].push_back(tin[u]); cnt[h[u]]++; for(int nxt : g[u]){ if(nxt == p) continue; self(self, nxt, u); } tout[u] = timer; cnt[h[u]]--; for(int c : heavy){ if(h[u] == c) continue; prep[c][h[u]] += cnt[c]; } }; dfs(dfs, 0, 0); for(int i=0;i<q;i++){ int a, b; cin>>a>>b; a--, b--; if(!prep[a].empty()){ cout<<prep[a][b]<<endl; } else{ int ans = 0; for(int u : reg[a]){ ans += int(lower_bound(v[b].begin(), v[b].end(), tout[u]) - lower_bound(v[b].begin(), v[b].end(), tin[u])); } cout<<ans<<endl; } } return 0; } /* [ ]Leu o problema certo??? [ ]Ver se precisa de long long [ ]Viu o limite dos fors (é n? é m?) [ ]Tamanho do vetor, será que é 2e5 em vez de 1e5?? [ ]Testar sample [ ]Testar casos de borda [ ]1LL no 1LL << i [ ]Testar mod (é 1e9+7, mesmo?, será que o mod não ficou negativo?) */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...