제출 #1336595

#제출 시각아이디문제언어결과실행 시간메모리
1336595sh_qaxxorov_571Regions (IOI09_regions)C++20
100 / 100
3226 ms34308 KiB
#include <bits/stdc++.h>
#include <map>
using namespace std;
const int MAXN = 200005;
const int MAXR = 25005;
const int BORDER = 450;
int N, R, Q;
int H[MAXN], tin[MAXN], tout[MAXN], timer;
vector<int> adj[MAXN], region_nodes[MAXR], heavy_regions;
vector<int> sorted_tins[MAXR];
int heavy_id[MAXR];
int ans_from_heavy[500][MAXR], ans_to_heavy[500][MAXR];
void dfs_time(int u) {
    tin[u] = ++timer;
    sorted_tins[H[u]].push_back(tin[u]);
    for (int v : adj[u]) dfs_time(v);
    tout[u] = timer;
}void dfs_heavy_from(int u, int cnt, int r_idx) {
    if (H[u] == heavy_regions[r_idx]) cnt++;
    else ans_from_heavy[r_idx][H[u]] += cnt;
    for (int v : adj[u]) dfs_heavy_from(v, cnt, r_idx);
}
int dfs_heavy_to(int u, int r_idx) {
    int cnt = (H[u] == heavy_regions[r_idx]);
    for (int v : adj[u]) cnt += dfs_heavy_to(v, r_idx);
    if (H[u] != heavy_regions[r_idx]) ans_to_heavy[r_idx][H[u]] += cnt;
    return cnt;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> N >> R >> Q;
    cin >> H[1];
    region_nodes[H[1]].push_back(1);
    for (int i = 2; i <= N; i++) {
        int s; cin >> s >> H[i];
        adj[s].push_back(i);
        region_nodes[H[i]].push_back(i);
    }

    dfs_time(1);
    for (int i = 1; i <= R; i++) {
        sort(sorted_tins[i].begin(), sorted_tins[i].end());
        if (region_nodes[i].size() > BORDER) {
            heavy_id[i] = heavy_regions.size();
            heavy_regions.push_back(i);
        }
    }

    for (int i = 0; i < heavy_regions.size(); i++) {
        dfs_heavy_from(1, 0, i);
        dfs_heavy_to(1, i);
    }

    while (Q--) {
        int r1, r2;
        cin >> r1 >> r2;
        if (region_nodes[r1].size() > BORDER) {
            cout << ans_from_heavy[heavy_id[r1]][r2] << endl;
        } else if (region_nodes[r2].size() > BORDER) {
            cout << ans_to_heavy[heavy_id[r2]][r1] << endl;
        } else {
            long long res = 0;
            for (int u : region_nodes[r1]) {
                res += lower_bound(sorted_tins[r2].begin(), sorted_tins[r2].end(), tout[u] + 1) -
                       lower_bound(sorted_tins[r2].begin(), sorted_tins[r2].end(), tin[u]);
            }
            cout << res << endl;
        }
        cout.flush();
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...