Cod sursa(job #2701321)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 30 ianuarie 2021 14:13:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
//
// Created by Toma Ariciu
// Copyright Ⓒ 2021 Toma Ariciu. All rights reserved.
//

#include <fstream>
#include <vector>
#include <math.h>

using namespace std;

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

int nr_noduri, nr_intervale, k;
int euler[400005], levels[400005], poz[100005], rmq[20][400005];
bool used[100005];
vector <int> G[100005];

void citire()
{
    fin>>nr_noduri>>nr_intervale;
    for(int i=2; i<=nr_noduri; i++)
    {
        int x;
        fin>>x;
        G[x].push_back(i);
    }
}

void init_euler(int nr, int lev)
{
    used[nr]=true;
    k++;
    euler[k]=nr;
    levels[k]=lev;
    poz[nr]=k;
    for(int i=0; i<G[nr].size(); i++)
    {
        if(used[G[nr][i]]==true)
            continue;
        init_euler(G[nr][i], lev+1);
        k++;
        euler[k]=nr;
        levels[k]=lev;
    }
}

void init_rmq()
{
    int x=log2(k);
    for(int j=1; j<=k; j++)
        rmq[0][j]=j;
    for(int i=1; i<=x; i++)
    {
        for(int j=1; j<k-(1<<(i-1)); j++)
        {
            rmq[i][j]=rmq[i-1][j];
            if(levels[rmq[i][j]] > levels[rmq[i-1][j+(1<<(i-1))]])
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
            ///fout<<rmq[i][j]<<' ';
        }
        ///fout<<'\n';
    }
}

void solve()
{
    for(int task=1; task<=nr_intervale; task++)
    {
        int a,b,st,dr;
        fin>>a>>b;
        st=poz[a];
        dr=poz[b];
        if(st>dr) swap(st,dr);
        int len=dr-st+1, ans;
        int loglen=log2(len);
        int left=len-(1<<loglen);
        ans=min(rmq[loglen][st], rmq[loglen][st+left]);
        ans=rmq[loglen][st];
        if(levels[rmq[loglen][st+left]] < levels[ans])
            ans=rmq[loglen][st+left];
        fout<<euler[ans]<<'\n';
    }
}

int main()
{
    citire();
    init_euler(1, 0);
    init_rmq();
    solve();
    return 0;
}