Cod sursa(job #3260726)

Utilizator sergioneUngureanu Sergiu sergione Data 3 decembrie 2024 15:47:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <fstream>
#include <vector>
#define MAX 100005
#define LOG 20

using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");

vector<int> tree[MAX];
vector<vector<int>> up;
vector<int> depth;

void dfs(int node, int parent)
{
    up[node][0] = parent;
    for(int i = 1; i < LOG; i++)
    {
        if(up[node][i - 1] != -1)
        {
            up[node][i] = up[up[node][i - 1]][i - 1];
        }
        else
        {
            up[node][i] = -1;
        }
    }

    for(auto neighbor : tree[node])
    {
        if(neighbor != parent)
        {
            depth[neighbor] = depth[node] + 1;
            dfs(neighbor, node);
        }
    }
}

void preprocess(int root)
{
    up.assign(MAX, vector<int>(LOG + 1, -1));
    depth.assign(MAX, 0);
    dfs(root, -1);
}

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 & (1 << i))
            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()
{
    int n, m;
    cin>>n>>m;
    for(int i = 1; i < n; i++)
    {
        int node;
        cin>>node;
        tree[node].push_back(i + 1);
        tree[i + 1].push_back(node);
    }
    int root = 1;
    preprocess(root);
    for(int i = 0; i < m; i++)
    {
        int a, b;
        cin>>a>>b;
        cout<<lca(a,b)<<'\n';
    }
}