Cod sursa(job #3122311)

Utilizator 100pCiornei Stefan 100p Data 18 aprilie 2023 16:27:36
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>

#define MAX 100000
#define FILES freopen("lca.in","r",stdin);\
              freopen("lca.out","w",stdout);

using namespace std;

vector<int> v[MAX + 5];
int n, q, up[MAX + 5][17], Time;

vector<bool> check(MAX + 5);

int levels;

int nodeIn[MAX + 5], nodeOut[MAX + 5];

inline void dfs(int x, int parent)
{
    check[x] = 1;
    Time++;
    nodeIn[x] = Time;
    if(parent != -1)
        up[x][0] = parent;

    for(int i = 1;i <= levels; ++i)
        up[x][i] = up[up[x][i - 1]][i - 1];

    for(auto i : v[x])
    {
        if(!check[i])
            dfs(i, x);
    }
    Time++;
    nodeOut[x] = Time;
}

inline bool isAncestor(int a, int b)
{
    return nodeIn[b] >= nodeIn[a] && nodeOut[b] <= nodeOut[a];
}

inline int lca(int a,int b)
{
    if(isAncestor(a, b))
        return a;
    if(isAncestor(a, b))
        return b;
    int exp = levels;
    while(exp >= 0)
    {
        while(exp >= 0 && !up[a][exp])
            exp--;
        while(exp >= 0 && isAncestor(up[a][exp], b))
            exp--;
        if(exp >= 0)
            a = up[a][exp];
    }
    return up[a][0];
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    FILES
    std::cin >> n >> q;
    for(int i = 2;i <= n; ++i)
    {
        int a;
        std::cin >> a;
        v[i].push_back(a), v[a].push_back(i);
    }
    levels = log2(n);
    dfs(1, -1);
    for(int i = 1;i <= q; ++i)
    {
        int a, b;
        std::cin >> a >> b;
        std::cout << lca(a, b) << '\n';
    }
}