제출 #1339374

#제출 시각아이디문제언어결과실행 시간메모리
1339374AMel0nRegions (IOI09_regions)C++20
100 / 100
3952 ms47828 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

signed main() {
    cin.tie(0); ios::sync_with_stdio(false);
    const ll SQRT = 300;
    ll N, R, Q;
    cin >> N >> R >> Q;
    vector<ll> reg(N);
    vector<vector<ll>> in_reg(R);
    vector<vector<ll>> adj(N);
    for(ll i = 0; i < N; i++) {
        if (i) {
            ll p; cin >> p; p--;
            adj[p].push_back(i);
        } 
        cin >> reg[i]; reg[i]--;
        in_reg[reg[i]].push_back(i);
    }
    vector<ll> in(N), out(N);
    ll cnt = 0;
    function<void(ll)> tour = [&](ll v) {
        in[v] = cnt++;
        for(ll &u: adj[v]) tour(u);
        out[v] = cnt++;
    };
    tour(0);
    vector<vector<ll>> pos(R); // for every region r, the sorted positions of each person relative to euler tour timing
    for(ll i = 0; i < N; i++) {
        pos[reg[i]].push_back(in[i]);
    }
    vector<vector<ll>> heavy(R); // for every region r that is heavy, the value for every other region
    function<void(ll, ll, ll)> dfs = [&](ll v, ll r, ll anc_cnt) {
        heavy[r][reg[v]] += anc_cnt;
        if (reg[v] == r) anc_cnt++;
        for(ll &u: adj[v]) dfs(u, r, anc_cnt);
    };
    for(ll r = 0; r < R; r++) {
        sort(pos[r].begin(), pos[r].end());
        if (in_reg[r].size() > SQRT) {
            heavy[r].resize(R);
            dfs(0, r, 0);
        }
    }
    for(ll q = 0; q < Q; q++) {
        ll a, b; cin >> a >> b; a--, b--;
        if (in_reg[a].size() > SQRT) cout << heavy[a][b] << endl;
        else {
            ll re = 0;
            for(ll &v: in_reg[a]) {
                re += lower_bound(pos[b].begin(), pos[b].end(), out[v]) - 
                      lower_bound(pos[b].begin(), pos[b].end(), in[v]);
            }
            cout << re << endl;
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...