Cod sursa(job #2559106)

Utilizator Rares31100Popa Rares Rares31100 Data 26 februarie 2020 23:33:33
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <bits/stdc++.h>

using namespace std;

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

int n,q;
int vf[200001],urm[200001],last[100001],nr;
int eul[200001],nivel[200001],poz[100001],nrE;
int rmq[18][200001];

void adauga(int nod,int vec)
{
    vf[++nr]=vec;
    urm[nr]=last[nod];
    last[nod]=nr;
}

void Edfs(int nod,int from,int niv=1)
{
    eul[++nrE]=nod;
    nivel[nrE]=niv;
    poz[nod]=nrE;

    for(int k=last[nod];k;k=urm[k])
        if(vf[k]!=from)
        {
            Edfs(vf[k],nod,niv+1);
            eul[++nrE]=nod;
            nivel[nrE]=niv;
        }
}

void RMQ()
{
    for(int i=1;i<=nrE;i++)
        rmq[0][i]=i;

    int rMax=log2(nrE);

    for(int r=1,l=1;r<=rMax;r++,l*=2)
        for(int i=1;i<=nrE-2*l+1;i++)
            if( nivel[ rmq[r-1][i] ] < nivel[ rmq[r-1][i+l] ] )
                rmq[r][i]=rmq[r-1][i];
            else
                rmq[r][i]=rmq[r-1][i+l];
}

int lca(int a,int b)
{
    a=poz[a];b=poz[b];
    if(a>b)
        swap(a,b);

    int r=log2(b-a+1);
    int l=1<<r;
    int minim;

    if( nivel[ rmq[r][a] ] < nivel[ rmq[r][b-l+1] ] )
        minim=rmq[r][a];
    else
        minim=rmq[r][b-l+1];

    return eul[minim];
}

int main()
{
    in>>n>>q;

    for(int tata,i=2;i<=n;i++)
    {
        in>>tata;

        adauga(i,tata);
        adauga(tata,i);
    }

    Edfs(1,0);
    RMQ();

    for(int a,b,k=1;k<=q;k++)
    {
        in>>a>>b;
        out<<lca(a,b)<<'\n';
    }

    return 0;
}