Cod sursa(job #3225945)

Utilizator TaniaKallosKallos Tania TaniaKallos Data 19 aprilie 2024 13:37:33
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
//#include <iostream>
#include <fstream>

using namespace std;

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


const int N = 1e5, LOG = 16;
int n, queries, log;
int t[LOG+1][N+1], lev[N+1];


int get_lev(int node)
{
    if (lev[node] != 0)
        return lev[node];
    return 1 + get_lev( t[0][node] );
}

int get_kth_daddy(int node, int k)
{
    int ans = node;
    for (int bit = 0; (1 << bit) <= k; bit++)
    {
        if (k & (1 << bit))
            ans = t[bit][ans];
    }
    return ans;
}

int lca(int x, int y)
{
    if (lev[x] < lev[y])
        swap(x, y);
    
    x = get_kth_daddy(x, lev[x] - lev[y]);

    if (x == y)
        return x;
    
    for (int pw2 = log; pw2 >= 0; pw2--)
    {
        if (t[pw2][x] != t[pw2][y])
        {
            x = t[pw2][x];
            y = t[pw2][y];
        }
    }

    return t[0][x];
}


int main()
{
    cin >> n >> queries;

    for (int i = 2; i <= n; i++)
        cin >> t[0][i];
    

    for (log = 0; (1 << log) <= n; log++);
    log--;

    for (int i = 1; i <= log; i++)
        for (int j = 1; j <= n; j++)
            t[i][j] = t[i - 1][ t[i - 1][j] ];
    
    lev[1] = 1;
    for (int i = 2; i <= n; i++)
        lev[i] = get_lev(i);
    

    for (int q = 1; q <= queries; q++)
    {
        int x, y;
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }


    return 0;
}