Cod sursa(job #2883210)

Utilizator stefanvoicaVoica Stefan stefanvoica Data 1 aprilie 2022 12:12:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.3 kb
#include<bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout("lca.out");
const int dim=200002;

int n,k,pos[dim],apr[dim],p[20];
vector<int>a[dim];

struct el
{
    int nod,niv;
}rmq[20][dim];

void euler(int x,int tata,int h)
{
    rmq[0][++k]={x,h};
    pos[x]=k;
    for (int y:a[x])
        if (y!=tata)
    {
        euler(y,x,h+1);
        rmq[0][++k]={x,h};
    }
}

el mini (el a,el b)
{
    if (a.niv<b.niv)
        return a;
    return b;
}

void precalc()
{
    int put=1,exp=0;
    p[0]=1;
    for (int i=1;i<=k;i++)
    {
        if (p[exp]*2==i)
        {
            p[++exp]=2*put;
            put*=2;
        }
        apr[i]=exp;
    }
    for (int i=1;i<=19;i++)
        for (int j=1;j<=k-p[i]+1;j++)
        rmq[i][j]=mini(rmq[i-1][j],rmq[i-1][j+p[i-1]]);
}

void query (int x,int y)
{
    if (x>y)
        swap(x,y);
    int lg=y-x+1;
    el lca=mini(rmq[apr[lg]][x],
                rmq[apr[lg]][y-p[apr[lg]]+1]);
    fout<<lca.nod<<'\n';
}

int main ()
{
    int q,x,y;
    fin>>n>>q;
    for (int i=2;i<=n;i++)
    {
        fin>>x;
        a[x].push_back(i);
        a[i].push_back(x);
    }
    euler(1,0,1);
    precalc();
    while (q--)
    {
        fin>>x>>y;
        query(pos[x],pos[y]);
    }
}