Cod sursa(job #3003807)

Utilizator RobertlelRobert Robertlel Data 15 martie 2023 22:42:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
#include <iostream>
#include <set>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

ifstream f ("lca.in");
ofstream g ("lca.out");

int euler[200005] , k , first[200005] , niv[200005] , x , q , n , rmq[19][200005] , y;

vector <int> v[200005];

void dfs (int nod , int lvl)
{
    euler[++k] = nod;
    first[nod] = k;
    niv[nod] = lvl;
    for (int i = 0 ; i < v[nod].size() ; i++)
    {
        int vecin = v[nod][i];
        dfs (vecin , lvl + 1);
        euler[++k] = nod;
        first[nod] = k;
    }

}

int querry (int a , int b)
{
    int lng = b - a + 1;
    int j = 0;
    while ((1 << j) <= lng)
        j++;
    j--;
    if (niv[rmq[j][a]] < niv[rmq[j][b -  (1 << j) + 1]])
        return rmq[j][a];
    else
        return rmq[j][b - (1 << j) + 1];
}

int main()
{
    f >> n >> q;
    for (int i = 2 ; i <= n ; i++)
    {
        f >> x;
        v[x].push_back (i);
    }

    dfs (1 , 0);

    for (int i = 1 ; i <= k ; i++)
        rmq[0][i] = euler[i];

    for (int i = 1 ; (1 << i) <= k ; i++)
    {
        for (int j = 1 ; j + (1 << i) - 1 <= k ; j++)
        {
            if (niv[rmq[i - 1][j]] < niv[rmq[i - 1][j + (1 << (i - 1))]])
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
    }
    for (int i = 1 ; i <= q ; i++)
    {
        f >> x >> y;
        if (first[x] > first[y])
            g << querry (first[y] , first[x]) << '\n';
        else
            g << querry (first[x] , first[y]) << '\n';
    }
    return 0;
}