Cod sursa(job #3233257)

Utilizator MirceaDonciuLicentaLicenta Mircea Donciu MirceaDonciuLicenta Data 2 iunie 2024 20:59:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <iostream>
#include <vector>
#include <cmath>
#include <fstream>

using namespace std;

const int MAXN = 100005;
const int LOG = 20;

vector<int> adj[MAXN];
int up[MAXN][LOG];
int depth[MAXN];

void dfs(int v, int p) {
    up[v][0] = p;
    for (int i = 1; i < LOG; i++) {
        up[v][i] = up[up[v][i-1]][i-1];
    }
    for (int u : adj[v]) {
        if (u != p) {
            depth[u] = depth[v] + 1;
            dfs(u, v);
        }
    }
}

int lca(int u, int v) {
    if (depth[u] < depth[v])
        swap(u, v);
    int diff = depth[u] - depth[v];
    for (int i = 0; i < LOG; i++) {
        if ((diff >> i) & 1) {
            u = up[u][i];
        }
    }
    if (u == v)
        return u;
    for (int i = LOG-1; i >= 0; i--) {
        if (up[u][i] != up[v][i]) {
            u = up[u][i];
            v = up[v][i];
        }
    }
    return up[u][0];
}

int main() {
    ifstream infile("lca.in");
    ofstream outfile("lca.out");

    int n, m;
    infile >> n >> m;

    for (int i = 2; i <= n; i++) {
        int parent;
        infile >> parent;
        adj[parent].push_back(i);
        adj[i].push_back(parent);
    }

    depth[1] = 0;
    dfs(1, 1);

    for (int i = 0; i < m; i++) {
        int u, v;
        infile >> u >> v;
        outfile << lca(u, v) << endl;
    }

    infile.close();
    outfile.close();

    return 0;
}