Cod sursa(job #2822470)

Utilizator lolismekAlex Jerpelea lolismek Data 23 decembrie 2021 23:45:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int N = 1e5 + 1, LOG = 17;
int dp[N + 10][LOG + 10], depth[N + 10];
vector <int> adj[N];
bitset <N> viz;

void dfs(int nod) {
    viz[nod] = 1;
    for (auto vec : adj[nod]) {
        if (!viz[vec]) {
            depth[vec] = depth[nod] + 1;
            dfs(vec);
        }
    }
}

int lca(int a, int b) {
    if (depth[a] < depth[b]) swap(a, b);
    // le aducem la acelasi nivel(eficient, cu binary lifting):
    int dif = depth[a] - depth[b];
    for (int i = LOG - 1; i >= 0; i--)
        if (dif & (1 << i))
            a = dp[a][i];

    if (a == b) return a;

    for (int i = LOG - 1; i >= 0; i--) {
        if (dp[a][i] != dp[b][i]) { // prin aceasta conditie ne asiguram ca gasim minimul posibil 
            a = dp[a][i];
            b = dp[b][i];
        }
    }
    return dp[a][0];
}


int main() {
    int n, q;
    fin >> n >> q;
    for (int i = 2; i <= n; i++) {
        int x;
        fin >> x;
        dp[i][0] = x;
        adj[i].push_back(x);
        adj[x].push_back(i);
    }
    for (int j = 1; (1 << j) <= n; j++)
        for (int i = 1; i <= n; i++)
            dp[i][j] = dp[dp[i][j - 1]][j - 1];

    dfs(1);
    while (q--) {
        int a, b;
        fin >> a >> b;
        fout << lca(a, b) << '\n';
    }
    return 0;
}