Submission #1355193

#TimeUsernameProblemLanguageResultExecution timeMemory
1355193chan_uuRegions (IOI09_regions)C++20
100 / 100
1014 ms39744 KiB
#include <bits/stdc++.h>
#define ASSERT(x) while (!(x))
using namespace std;

const int B = 456;
long long id[25252], ans1[B][25252], ans2[B][25252], H[202020], in[202020], out[202020], pre[202020];
vector<int> reg[25252], T[202020];
vector<pair<int,int>> reg_int[25252];

void dfs(int v){
    static int ii = 0;
    in[v] = ++ii;
    for (int i : T[v])
        dfs(i);
    out[v] = ii;
}

void go(int v, int r, int c = 0){
    if (H[v] == r) c++;
    else{
        ans1[id[r]][H[v]] += c;
        ans2[id[r]][H[v]] += pre[out[v]] - pre[in[v] - 1];
    }
    for (int i : T[v])
        go(i, r, c);
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(0);
    int N, R, Q;
    cin >> N >> R >> Q;
    cin >> H[1];
    reg[H[1]].push_back(1);
    for (int i = 2, p; i <= N; i++){
        cin >> p >> H[i];
        reg[H[i]].push_back(i);
        T[p].push_back(i);
    }
    dfs(1);
    memset(id, -1, sizeof id);
    for (int i = 1, ii = 0; i <= R; i++){
        if (reg[i].empty()) continue;
        sort(reg[i].begin(), reg[i].end(), [&](int a, int b){ return in[a] < in[b]; });
        for (int x : reg[i]) {
            reg_int[i].emplace_back(in[x], 0);
            reg_int[i].emplace_back(out[x], 1);
        }
        sort(reg_int[i].begin(), reg_int[i].end());
        if (reg[i].size() > B){
            id[i] = ii++;
            for (int j : reg[i]) pre[in[j]] = 1;
            for (int j = 1; j <= N; j++) pre[j] += pre[j-1];
            go(1, i);
            memset(pre, 0, sizeof pre);
        }
        
    }
    while (Q--){
        int r1, r2;
        cin >> r1 >> r2;
        if (id[r1] != -1) cout << ans1[id[r1]][r2] << endl;
        else if (id[r2] != -1) cout << ans2[id[r2]][r1] << endl;
        else {
            int idx = 0, cc = 0, ans = 0;
            for (int x : reg[r2]){
                pair<int,int> now = {in[x], 0};
                while (idx < reg_int[r1].size() and reg_int[r1][idx] <= now){
                    if (reg_int[r1][idx].second) cc--;
                    else cc++;
                    idx++;
                }
                ans += cc;
            }
            cout << ans << endl;
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...