Mai intai trebuie sa te autentifici.

Cod sursa(job #2648552)

Utilizator Marius7122FMI Ciltea Marian Marius7122 Data 11 septembrie 2020 14:05:45
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.31 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
 
ifstream fin("lca.in");
ofstream fout("lca.out");
 
const int N = 100005;
const int LOG = 17;

int n, q;
int anc[LOG][N], d[N];
 
void computeDepth(int x)
{
    if(anc[0][x] == 0 || d[x])
        return;
    
    if(d[anc[0][x]] == 0 && anc[0][x] != 0)
        computeDepth(anc[0][x]);
    
    d[x] = d[anc[0][x]] + 1;

}

void precompute()
{
    for(int i = 1; i <= n; i++)
        computeDepth(i);

    for(int lvl = 1; (1 << lvl) <= n; lvl++)
        for(int i = 1; i <= n; i++)
            anc[lvl][i] = anc[lvl-1][anc[lvl-1][i]];
}

int solveQuery(int x, int y)
{
    if(d[x] < d[y])
        swap(x, y);

    // aducerea pe acelasi nivel
    int dif = d[x] - d[y];
    for(int lvl = 0; (1 << lvl) <= n; lvl++)
        if(dif & (1 << lvl))
            x = anc[lvl][x];

    // gasesc stramosul comun
    if(x == y)
        return x;
    for(int lvl = LOG - 1; lvl >= 0; lvl--)
        if(anc[lvl][x] != anc[lvl][y])
        {
            x = anc[lvl][x];
            y = anc[lvl][y];
        }
    return anc[0][x];
}

int main()
{
	fin >> n >> q;
    for(int i = 2; i <= n; i++)
        fin >> anc[0][i];

    precompute();
    while(q--)
    {
        int x, y;
        fin >> x >> y;
        fout << solveQuery(x, y) << '\n';
    }
    return 0;
}