Cod sursa(job #3187016)

Utilizator popabogdanPopa Bogdan Ioan popabogdan Data 26 decembrie 2023 22:50:15
Problema Stramosi Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.44 kb
#include <bits/stdc++.h>

using namespace std;

const int N_MAX = 250000;

struct BinaryLifting {
    int depth[N_MAX + 5];
    int jump[N_MAX + 5];
    int parent[N_MAX + 5];

    void init() {
        depth[0] = 0;
        jump[0] = parent[0] = 1;
    }

    void add_leaf(int node, int par) {
        depth[node] = 1 + depth[par];
        parent[node] = par;
        
        if(depth[jump[par]] - depth[par] == depth[jump[jump[par]]] - depth[jump[par]]) {
            jump[node] = jump[jump[par]];
        }
        else {
            jump[node] = par;
        }
    }

    int find(int node, int d) {
        while(depth[node] > d) {
            if(depth[jump[node]] > d) {
                node = jump[node];
            }
            else {
                node = parent[node];
            }
        }
        return node;
    }
};

BinaryLifting T;
int N, M;
vector <int> G[N_MAX + 5];

void DFS(int node) {
    for(auto it : G[node]) {
        T.add_leaf(it, node);
        DFS(it);
    }
}

int main() {
#ifndef LOCAL
    freopen("stramosi.in", "r", stdin);
    freopen("stramosi.out", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> N >> M;
    for(int i = 1; i <= N; i++) {
        int x;
        cin >> x;
        G[x].push_back(i);
    }

    DFS(0);

    while(M--) {
        int p, q;
        cin >> p >> q;
        q = min(q, T.depth[p]);
        cout << T.find(p, T.depth[p] - q) << "\n";
    }
    return 0;
}