Submission #1158103

#TimeUsernameProblemLanguageResultExecution timeMemory
1158103CodeLakVNRegions (IOI09_regions)C++20
0 / 100
68 ms28968 KiB
#include <bits/stdc++.h>
using namespace std;

#define task "REGIONS"
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FOD(i, a, b) for (int i = (a); i >= (b); i--)
#define F first
#define S second

const int N = (int)2e5 + 5;
const int BLOCK = 450;

int numNode, numQuery, numRegions;
vector<int> adj[N];
vector<pair<int, int>> regions[25005];
int region[N];

int timer = 0;
int in[N], out[N];

void dfs(int u, int p) {
    in[u] = ++timer;
    for (int v : adj[u]) if (v != p) 
        dfs(v, u);
    out[u] = timer;
}

struct NODE {
    int u, region, timer;

    bool operator < (const NODE &other) const {
        return timer < other.timer;
    }
};
vector<NODE> nodes;

int ans[BLOCK][25005];
int id[25005];

void solve(int r1, int r2) {
    int res = 0;
    for (auto [t, u] : regions[r1]) {
        if (u == 0) break;
        int l = lower_bound(regions[r2].begin(), regions[r2].end(), make_pair(t, N)) - regions[r2].begin();
        int r = upper_bound(regions[r2].begin(), regions[r2].end(), make_pair(out[u], N)) - regions[r2].begin() - 1;
        res += max(0, r - l + 1);
    }
    cout << res << "\n";
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> numNode >> numRegions >> numQuery;
    FOR(i, 1, numNode) {
        int p = -1;
        if (i == 1) cin >> region[i];
        else cin >> p >> region[i];
        if (p != -1) adj[p].push_back(i);
    }

    dfs(1, -1);

    FOR(i, 1, numNode) {
        regions[region[i]].push_back({in[i], i});
        nodes.push_back({i, region[i], in[i]});        
    }

    in[0] = INT_MAX;
    FOR(r, 1, numRegions) {
        regions[r].push_back({in[0], 0});
        sort(regions[r].begin(), regions[r].end());
    }

    sort(nodes.begin(), nodes.end());

    // precomputing for queries that has R1 >= BLOCK - O(BLOCK * N)
    int cnt = 0;
    FOR(r, 1, numRegions) {
        int m = regions[r].size();
        if (m >= BLOCK) {
            id[r] = ++cnt;
            int i = 0, j = 0;
            while (i < m && j < numNode) {
                if (out[regions[r][i].S] < nodes[j].timer) i++;
                if (nodes[j].timer >= in[regions[r][i].S] && nodes[j].timer <= out[regions[r][i].S])
                    ans[cnt][nodes[j].region]++;
                j++;
            }
        }
    }

    while (numQuery--) {
        int r1, r2;
        cin >> r1 >> r2;
        if ((int)regions[r1].size() >= BLOCK) cout << ans[id[r1]][r2] << "\n";
        else {
            solve(r1, r2);
        }
    }

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