Cod sursa(job #3242497)

Utilizator CondoracheAlexandruCondorache Alexandru CondoracheAlexandru Data 12 septembrie 2024 15:15:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>
#define ll long long
using namespace std;

int timer;

void dfs(int v, int p, int l, const vector<vector<int>>& adj, vector<int>& timein, vector<int>& timeout, vector<vector<int>>& up) {
    timein[v] = ++timer;
    up[v][0] = p;
    for (int i = 1; i <= l; i++) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (int u : adj[v]) {
        if (u != p) {
            dfs(u, v, l, adj, timein, timeout, up);
        }
    }
    timeout[v] = ++timer; 
}

bool is_ancestor(int u, int v, const vector<int>& timein, const vector<int>& timeout) {
    return (timein[u] <= timein[v]) && (timeout[u] >= timeout[v]);
}

int lca(int u, int v, int l,const vector<vector<int>>& up, const vector<int>& timein, const vector<int>& timeout) {
    if (is_ancestor(u, v, timein, timeout)) {
        return u;
    }
    if (is_ancestor(v, u, timein, timeout)) {
        return v;
    }
    for (int i = l; i >= 0; i--) {
        if (!is_ancestor(up[u][i], v, timein, timeout)) {
            u = up[u][i];
        }
    }
    return up[u][0];
}

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

void solve() {
    int n, m;
    fin >> n >> m;
    vector<vector<int>> adj(n, vector<int>());
    for (int i = 0; i < n - 1; i++) {
        int x;
        fin >> x;
        x--;
        adj[x].push_back(i + 1);
    } 
    int l = ceil(log2(n));
    vector<int> timein(n), timeout(n);
    vector<vector<int>> up(n, vector<int>(l + 1));
    dfs(0, 0, l, adj, timein, timeout, up);
    while (m--) {
        int u, v;
        fin >> u >> v;
        u--;
        v--;
        fout << 1 + lca(u, v, l, up, timein, timeout) << endl;
    }
}

int main() {
    int t = 1;
    // fin >> t;
    while (t--) {
        solve();
    }
}