제출 #1335323

#제출 시각아이디문제언어결과실행 시간메모리
1335323vyaductRegions (IOI09_regions)C++20
100 / 100
2701 ms129756 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<int> h(n), cnt(r, 0);
  cin>>h[0]; h[0]--; cnt[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]--;
    cnt[h[i]]++;
  }

  int BLK = sqrt(n);
  map<int, unordered_map<int, int>> val;

  auto dfs = [&](auto &&dfs, int v, int par, int value, int par_reg) -> void {
    if (h[v] != par_reg && value > 0) val[par_reg][h[v]]+=value;
    for (int u : Tree[v]){
      if (u == par) continue;
      dfs(dfs, u, v, value + (h[v] == par_reg), par_reg);
    }
  };

  REP(t, 0, r-1) if (cnt[t] >= BLK) dfs(dfs, 0, -1, 0, t); 
  
  int timer = 0;
  vector<int> start(n);
  vector<int> finish(n);
  vector<int> inv_start(n);
  vector<vector<int>> comp(r);
  auto tour = [&](auto &&tour, int v, int par) -> void {
    start[v] = timer++;
    inv_start[start[v]] = v;
    comp[h[v]].push_back(start[v]);
    for (int u : Tree[v]){
      if (u == par) continue;
      tour(tour, u, v);
    }
    finish[v] = timer;
  };

  tour(tour, 0, -1);

  while(q--){
    int r1, r2; cin>>r1>>r2;
    r1--, r2--;
    if (cnt[r1] < BLK){
      int ans = 0;
      for (int tin: comp[r1]){
        int node = inv_start[tin];
        ans += lower_bound(ALL(comp[r2]), finish[node]) - lower_bound(ALL(comp[r2]), start[node]);
      }
      cout << ans << endl;
    } else {
      cout << val[r1][r2] << 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...