CCCPaste

Untitled

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
const int logn = 20;
vector graph[maxn];
int in_time[maxn], out_time[maxn];
int timer;
int up_node[maxn][25];
void dfs(int node, int prev) {
    in_time[node] = ++timer;
    up_node[node][0] = prev;
    for(int i = 1; i < logn; i++) {
        up_node[node][i] = up_node[up_node[node][i - 1]][i - 1];
    }
    for(int i = 0; i < (int) graph[node].size(); i++) {
        int neigh = graph[node][i];
        if(neigh != prev) {
            dfs(neigh, node);
        }
    }
    out_time[node] = ++timer;
}
bool is_ancestor(int A, int B) {
    return in_time[A] <= in_time[B] and out_time[A] >= out_time[B];
}
int LCA(int A, int B) {
    if(is_ancestor(A, B)) {
        return A;
    }
    if(is_ancestor(B, A)) {
        return B;
    }
    
    for(int i = logn - 1; i >= 0; i--) {
        if(!is_ancestor(up_node[A][i], B)) {
            A = up_node[A][i];
        }
    }
    return up_node[A][0];
}
int main() {
    ios_base::sync_with_stdio(false);
//    ifstream cin("in.txt");
    int n, q;
    cin >> n >> q;
    for(int i = 2; i <= n; i++) {
        int p;
        cin >> p;
        graph[p].push_back(i);
        graph[i].push_back(p);
        
    }
    dfs(1, 1);
    for(int i =0 ; i < q; i++) {
        int a, b;
        cin >> a >> b;
        cout << LCA(a, b) << endl;
    }
    return 0;
}

// 200000