Cod sursa(job #2518767)

Utilizator ApostolIlieDanielApostol Daniel ApostolIlieDaniel Data 6 ianuarie 2020 16:23:06
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.36 kb
#include <bits/stdc++.h>

using namespace std;


const int LG = 20, N = 1e6;
int p[LG][1 + N];
int d[1 + N];
vector <int> gr[1 + N];
#define pb push_back

void dfs (int node, int f) {
    p[0][node] = f;
    d[node] = d[f] + 1;
    for (auto son : gr[node])
        dfs (son, node);
}
int n;

void lift () {
    for (int k = 1; k < LG; k++)
        for (int i = 1; i <= n; i++)
            p[k][i] = p[k - 1][p[k - 1][i]];
}

int lca (int a, int b) {
    int k;
    k = LG - 1;
    while (d[a] > d[b]) {
        if (d[p[k][a]] >= d[b])
            a = p[k][a];
        k--;
    }
    k = LG - 1;
    while (d[a] < d[b]) {
        if (d[p[k][b]] >= d[a])
            b = p[k][b];
        k--;
    }
    k = LG - 1;
    while (k >= 0) {
        if (p[k][a] != p[k][b])
            a = p[k][a], b = p[k][b];
        k--;
    }
    if (a != b)
        a = p[0][a];
    return a;
}

int main () {
    freopen ("lca.in", "r", stdin);
    freopen ("lca.out", "w", stdout);

    ios::sync_with_stdio (false);
    cin.tie (0); cout.tie (0);

    int m;
    cin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int par;
        cin >> par;
        gr[par].pb (i);
    }

    dfs (1, 0);
    lift ();

    while (m--) {
        int x, y;
        cin >> x >> y;
        cout << lca (x, y) << "\n";
    }

    return 0;
}