Submission #1335300

#TimeUsernameProblemLanguageResultExecution timeMemory
1335300vyaductRegions (IOI09_regions)C++20
0 / 100
46 ms34328 KiB
#include<bits/stdc++.h>
using namespace std;

#define REP(i, from, to) for (ll i=(from);i<=(to);++i)
#define PER(i, from, to) for (ll i=(from);i>=(to);--i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) (ll)(x).size()
#define PB push_back
#define MP make_pair
#define F first
#define S second
typedef long long ll;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;

int last_true(int lo, int hi, function<bool(int)> f){
  lo--;
  while(lo < hi){
    int mid = lo + (hi-lo+1)/2;
    if (f(mid)) lo = mid;
    else hi = mid-1;
  }
  return lo;
}

int first_true(int lo, int hi, function<bool(int)> f) {
  hi++;
  while (lo < hi) {
    int mid = lo + (hi - lo)/2;
    if (f(mid)) hi = mid; 
    else  lo = mid + 1;
  }
  return lo;
}

void solve(){
  int n,r,q; cin>>n>>r>>q;
  vector<vector<int>> Tree(n);
  vector<multiset<int>> reg(n);
  vector<int> h(n), cnt(r, 0);
  cin>>h[0]; h[0]--; cnt[h[0]]++; reg[0].insert(h[0]);
  REP(i, 1, n-1) {
    int par; cin>>par; par--;
    Tree[par].PB(i);
    Tree[i].PB(par);
    cin>>h[i]; h[i]--;
    reg[i].insert(h[i]);
    cnt[h[i]]++;
  }
  vector<array<int, 4>> qr(q);
  REP(i, 0, q-1) {
    cin>>qr[i][0]; qr[i][0]--;
    cin>>qr[i][1]; qr[i][1]--;
    qr[i][2] = i;
    qr[i][3] = 0;
  }

  sort(ALL(qr));

  int BLK = sqrt(n);

  auto dfs_less = [&](auto &&dfs_less, int v, int par) -> void {
    for (int u : Tree[v]){
      if (u == par) continue;
      dfs_less(dfs_less, u, v);
      if (reg[u].size() > reg[v].size()) swap(reg[u], reg[v]);
      for (int x : reg[u]) reg[v].insert(x);
    }
    if (cnt[h[v]] < BLK){
      int L = first_true(0, q-1, [&](ll j) { return qr[j][0] >= h[v]; });
      int R = last_true(0, q-1, [&](ll j) { return qr[j][0] <= h[v]; });
      REP(i, L, R){
        qr[i][3] += reg[v].count(qr[i][1]);
      }
    }
  };
  map<int, map<int, int>> val;
  auto dfs_greater = [&](auto &&dfs_greater, int v, int par, int value, int par_reg) -> void {
    if (h[v] == par_reg) value++;
    else val[par_reg][h[v]]+=value;
    for (int u : Tree[v]){
      if (u == par) continue;
      dfs_greater(dfs_greater, u, v, value, par_reg);
    }
  };

  dfs_less(dfs_less, 0, -1); 
  REP(root, 0, n-1) if (cnt[h[root]] >= BLK) dfs_greater(dfs_greater, 0, -1, 0, h[root]); 
  REP(i, 0, q-1) if (cnt[qr[i][0]] >= BLK) qr[i][3] = val[qr[i][0]][qr[i][1]]/2;
  vector<int> ans(q);
  REP(i, 0, q-1) ans[qr[i][2]] = qr[i][3];
  REP(i, 0, q-1) cout << ans[i] << endl; 

}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  int tt=1;
  // cin>>tt;
  while(tt--) solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...