제출 #1300815

#제출 시각아이디문제언어결과실행 시간메모리
1300815tolgaRegions (IOI09_regions)C++20
100 / 100
2436 ms39524 KiB
#include <iostream>
#include <vector>
#include <algorithm>
typedef long long ll;

const int maxn = 5 + 2e5, maxr = 25005;
std::vector<int> edges[maxn];
int vert[maxn], tin[maxn], tout[maxn], timer = 0;
ll calc[505][maxr];

void dfs(int u) {
  tin[u] = ++timer;
  for (int v : edges[u])
    dfs(v);
  tout[u] = timer;
}

int sum = 0;
void heavy_dfs(int heavy_idx, int heavy_reg, int u, int sum) {
  calc[heavy_idx][vert[u]] += sum;
  sum += (vert[u] == heavy_reg);
  for (int v : edges[u])
    heavy_dfs(heavy_idx, heavy_reg, v, sum);
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);

  int n, r, q;
  std::cin >> n >> r >> q;

  std::vector<std::vector<int>> reg(r + 1);
  std::cin >> vert[1];
  reg[vert[1]].push_back(1);
  for (int i = 2; i <= n; i++) {
    int par;
    std::cin >> par >> vert[i];
    reg[vert[i]].push_back(i);
    edges[par].push_back(i);
  }

  dfs(1);

  std::vector<std::vector<int>> reg_timer(r + 1);
  std::vector<int> heavy_idx(r + 1, -1);
  int idx = 0;
  for (int i = 1; i <= r; i++) {
    std::sort(reg[i].begin(), reg[i].end(),
              [](int &a, int &b) { return tin[a] < tin[b]; });

    if (reg[i].size() * reg[i].size() > n) {
      heavy_idx[i] = idx;
      heavy_dfs(idx, i, 1, 0);
      idx++;
    }

    reg_timer[i].reserve(reg[i].size());
    for (int &v : reg[i])
      reg_timer[i].push_back(tin[v]);
  }

  while (q--) {
    int r1, r2;
    std::cin >> r1 >> r2;

    if (heavy_idx[r1] != -1) {
      std::cout << calc[heavy_idx[r1]][r2] << std::endl;
      continue;
    }

    ll ans = 0;
    for (int &u : reg[r1]) {
      int left =
          std::lower_bound(reg_timer[r2].begin(), reg_timer[r2].end(), tin[u]) -
          reg_timer[r2].begin();
      int right = std::upper_bound(reg_timer[r2].begin(), reg_timer[r2].end(),
                                   tout[u]) -
                  reg_timer[r2].begin();
      ans += right - left;
    }
    std::cout << ans << std::endl;
  }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...