Cod sursa(job #2975085)

Utilizator octavi26octavian octavi26 Data 5 februarie 2023 13:04:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.48 kb
#include <bits/stdc++.h>
#define N 100008
#define mod 1000000007

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n, q;
int T[N];
vector< int > g[N];
int ET[2 * N];
int last[2 * N];
int f[N];
int finv[N];
int R[2 * N][20];
int Log[2 * N];
int et = 1;
int m;

void Citire()
{
    int i;
    fin >> n >> q;
    for( i=2; i<=n; i++ )
    {
        fin >> T[i];
        g[T[i]].push_back(i);
    }
}

void DFS( int x )
{
    f[x] = et;
    finv[et] = x;
    et++;
    ET[++m] = f[x];
    last[f[x]] = m;
    for( auto y : g[x] )
    {
        DFS(y);
        ET[++m] = f[x];
        last[f[x]] = m;
    }
}

void Precalculare()
{
    Log[2] = 1;
    for( int i=3; i<=m; i++ )
        Log[i] = Log[i / 2] + 1;

    for( int i=1; i<=m; i++ )
        R[i][0] = ET[i];

    for( int j=1; j<=Log[m]; j++ )
        for( int i=1; i + (1 << (j - 1)) <= m; i++ )
            R[i][j] = min( R[i][j - 1], R[i + (1 << (j - 1))][j - 1] );
}

int lca( int x, int y )
{
    x = f[x];
    y = f[y];
    int a, b;
    int k, l;

    a = last[x];
    b = last[y];
    if( a > b )
        swap(a, b);

    k = b - a + 1;
    l = Log[k];

    return finv[min( R[a][l], R[b - (1 << l) + 1][l] )];
}

void Rezolvare()
{
    DFS(1);
    Precalculare();
    int x, y;
    while( q-- )
    {
        fin >> x >> y;
        fout << lca(x, y) << "\n";
    }
}

int main()
{
    Citire();
    Rezolvare();
    return 0;
}