CCCPaste

Untitled

#include 
#include 
using namespace std;
const int maxn = 1e5 + 10;;
typedef long long ll;
int n;
int up_node[maxn][22];
vector graph[maxn];
int c_time = 0;
int disc_time[maxn], finish_time[maxn];
int depth[maxn];
void dfs(int node, int parent) {
    c_time++;
    disc_time[node] = c_time;
    for(int neighbour : graph[node]) {
        if(neighbour != parent) {
            depth[neighbour] = depth[node] + 1;
            dfs(neighbour, node);
        }
    }
    finish_time[node] = c_time;
}
vector > v[maxn];
int lift_node(int node, int k) {
    for(int i = 0; i < 20; i++) {
        if(k & (1 << i)) {
            node = up_node[node][i];
        }
    }
    return node;
}
int main(){
    ios_base::sync_with_stdio(false);
    cin >> n;
    int root = -1;
    for(int i = 1; i <= n; i++) {
        cin >> up_node[i][0];
        if(up_node[i][0] == 0) {
            root = i;
            up_node[i][0] = -1;
        }
        else {
            graph[i].push_back(up_node[i][0]);
            graph[up_node[i][0]].push_back(i);
        }
    }
    
    for(int j = 1; j < 20; j++) {
        for(int i = 1; i <= n; i++) {
            if(up_node[i][j - 1] != -1) {
                up_node[i][j] = up_node[up_node[i][j - 1]][j - 1];
            }
        }
    }
    for(int i = 1; i <= n; i++) {
        if(up_node[i][0] == -1) {
            dfs(i, -1);
        }
    }
    for(int i = 1; i <= n; i++) {
        v[depth[i]].push_back(make_pair(disc_time[i], finish_time[i]));
    }
    for(int i = 1; i <= n; i++) {
        sort(v[i].begin(), v[i].end());
    }
    int q;
    cin >> q;
    while(q--) {
        int node, p;
        cin >> node >> p;
        if(depth[node] < p) {
            cout << 0 << " ";
            continue;
        }
        int ancestor = lift_node(node, p);
        int L = -1;
        int R = v[depth[node]].size();
        while(abs(R - L) > 1) {
            int mid = (L + R) / 2;
            if(v[depth[node]][mid].first < disc_time[ancestor]) {
                L = mid;
            }
            else {
                R = mid;
            }
        }
        int idx1 = R;
        L = -1;
        R = (int) v[depth[node]].size();
        while(abs(R - L) > 1) {
            int mid = (L + R) / 2;
            if(v[depth[node]][mid].first <= finish_time[ancestor]) {
                L = mid;
            }
            else {
                R = mid;
            }
        }
        cout << L - idx1  << " ";
    }
    return 0;
}