Submission #1368310

#TimeUsernameProblemLanguageResultExecution timeMemory
1368310altern23Regions (IOI09_regions)C++20
25 / 100
144 ms196608 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long

const int MAXN = 2e5;
const int SQRT = 300;

int H[MAXN+5], heavy[MAXN+5], tin[MAXN+5], tout[MAXN+5];
vector <int> adj[MAXN+5], isi[MAXN+5];
int dp[MAXN+5][MAXN/SQRT+5], sum[MAXN/SQRT+5][MAXN/SQRT+5], rev[MAXN+5][MAXN/SQRT+5], M, timer;

void dfs(int idx) {
      tin[idx] = ++timer;
      isi[H[idx]].push_back(tin[idx]);
      for (auto i : adj[idx]) {
            for (int j=1; j<=M; j++) rev[i][j] += rev[idx][j];
            if (heavy[idx]) rev[i][H[idx]]++;
            dfs(i);
            for (int j=1; j<=M; j++) {
                  dp[idx][j] += dp[i][j];
            }
      }
      if (heavy[idx]) {
            for (int j=1; j<=M; j++) {
                  sum[H[idx]][j] += dp[idx][j];
            }
            dp[idx][H[idx]]++;
      }
      tout[idx] = timer;
}

int main() {
      ios_base::sync_with_stdio(0); cin.tie(0);
      int tc = 1;
      // cin >> tc;
      while (tc--) {
            int N, R, Q; cin >> N >> R >> Q;
            vector <int> occ[R+5];

            cin >> H[1];
            occ[H[1]].push_back(1);

            for (int i=2; i<=N; i++) {
                  int P; cin >> P;
                  cin >> H[i];
                  occ[H[i]].push_back(i);
                  adj[P].push_back(i);
            }

            vector <int> id(R+5);

            for (int i=1; i<=R; i++) {
                  if (occ[i].size()>SQRT) {
                        id[i] = ++M;
                        for (auto x : occ[i]) {
                              H[x] = M;
                              heavy[x] = 1;
                        }
                  }
                  else id[i] = i;
            }

            dfs(1);

            for (int i=1; i<=Q; i++) {
                  int R1, R2; cin >> R1 >> R2;
                  if (occ[R2].size()>SQRT && occ[R1].size()>SQRT) {
                        cout << sum[id[R1]][id[R2]] << endl;
                  }
                  else if (occ[R1].size()>SQRT && occ[R2].size()<=SQRT) {
                        ll ans = 0;
                        for (auto x : occ[R2]) ans += rev[x][id[R1]];
                        cout << ans << endl;
                  }
                  else {
                        ll ans = 0;
                        for (auto x : occ[id[R1]]) {
                              ans += upper_bound(isi[id[R2]].begin(), isi[id[R2]].end(), tout[x])-lower_bound(isi[id[R2]].begin(), isi[id[R2]].end(), tin[x]);
                        }
                        cout << ans << endl;
                  }
            }

      }
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...