Cod sursa(job #3214947)

Utilizator TeodoraMaria123Serban Teodora Maria TeodoraMaria123 Data 14 martie 2024 16:23:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define MAX_N 100000

int n, m, L, timer;

bitset <MAX_N + 1> visited;
vector <int> tin, tout;
vector <vector <int> > graph;
vector <vector <int> > up;

bool isAncestor(int a, int b)
{
//    cout << a << " " << b << "\n" << tin[a] << " " << tin[b] << "\n" << tout[a] << " " << tout[b] << "\n\n";
    return (tin[a] <= tin[b]  &&  tout[b] <= tout[a]);
}

void dfs(int node, int parent)
{
    tin[node] = ++timer;
    visited[node] = 1;

    up[node][0] = parent;
    for(int i = 1; i <= L; i ++)
        up[node][i] = up[up[node][i - 1]][i - 1];

    for(int neighbour : graph[node])
    {
        if(!visited[neighbour])
            dfs(neighbour, node);
    }

    tout[node] = ++timer;
}

int lca(int a, int b)
{
    if(isAncestor(a, b))
        return a;
    if(isAncestor(b, a))
        return b;

//    cout << a << " " << b << "\n";
    for(int i = L; i >= 0; i --)
        if(!isAncestor(up[a][i], b))
            a = up[a][i];
    return up[a][0];
}

int main()
{
    ios_base ::sync_with_stdio(0);
    cin.tie(0);

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

    cin >> n >> m;
    graph.resize(n + 1);
    tin.resize(n + 1);
    tout.resize(n + 1);

    L = ceil(log2(n));
    up.assign(n + 1, vector <int> (L + 1));

    for(int i = 1; i < n; i ++)
    {
        int x;
        cin >> x;
        graph[x].pb(i + 1);
    }

    dfs(1, 1);
//    for(int i = 1; i <= n; i ++)
//    {
//        cout << "node " << i << " : ";
//        for(int x : graph[i])
//            cout << x << " ";
//        cout << "\n";
//    }

    for(int i = 1; i <= m; i ++)
    {
        int a, b;
        cin >> a >> b;
        cout << lca(a, b) << "\n";
    }
    return 0;
}