Cod sursa(job #2841152)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 29 ianuarie 2022 12:39:01
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.32 kb
#include <bits/stdc++.h>

using namespace std;
#ifdef INFOARENA
#define cin fin
#define cout fout
ifstream fin("lca.in");
ofstream fout("lca.out");
#endif // INFOARENA
vector <vector <int>> g;
vector <int> tin, tout;
vector <int> lift[20];
int n, l, q, u, v, x, y, timer;

void dfs(int v, int p)
{
    tin[v] = ++timer;
    lift[0][v] = p;
    for(int i = 1; i <= l; i++)
        lift[i][v] = lift[i - 1][lift[i - 1][v]];
    for(int u : g[v])
        if(u != p)
            dfs(u, v);
    tout[v] = ++timer;
}

bool is_ancestor(int u, int v)
{
    if(u == 0) return true;
    return tin[u] <= tin[v] && tout[u] >= tout[v];
}

void Input() {
    cin >> n >> q; g.resize(n + 1); tin.resize(n + 1); tout.resize(n + 1); timer = 0;
    l = ceil(log2(n));
    for(int i = 0; i <= l; i++)
        lift[i].resize(n + 1);
    for(int i = 2; i <= n; i++)
        cin >> x,
        g[i].push_back(x),
        g[x].push_back(i);
}

int lca(int a, int b) {
    if(is_ancestor(a, b)) return a;
    if(is_ancestor(b, a)) return b;
    for(int i = l; i >= 0; i--)
        if(!is_ancestor(lift[i][a], b))
            a = lift[i][a];
    return lift[0][a];
}

int main()
{
    Input();
    dfs(1, 0);
    for(int i = 1; i <= q; i++)
        cin >> u >> v,
        cout << lca(u, v) << "\n";
    return 0;
}