Cod sursa(job #2738412)

Utilizator AndreiD31Dragan Andrei AndreiD31 Data 5 aprilie 2021 20:00:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.35 kb
#include <bits/stdc++.h>

using namespace std;

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

vector <int> V[100100],euler;
int indice,first[100100],h[100100],viz[100100];

void parcurgere_euler(int nod)
{
    viz[nod]=1;
    indice++;
    if(first[nod]==0)first[nod]=indice;
    euler.push_back(nod);

    for(int i=0;i<V[nod].size();i++)
    {
        int vecin=V[nod][i];
        if(viz[vecin]==0)
        {
            h[vecin]=h[nod]+1;
            parcurgere_euler(vecin);

            indice++;
            euler.push_back(nod);
        }
    }
}

int n,m,i,N,k,x,y,pz1,pz2,lca,rmq[300100][20];
int main()
{
    f>>n>>m;
    for(i=2;i<=n;i++)
    {
        f>>x;
        V[x].push_back(i);
        V[i].push_back(x);
    }

    h[1]=1;
    parcurgere_euler(1);

    N=euler.size();
    for(i=1;i<=N;i++)rmq[i][0]=euler[i-1];

    for(k=1;(1<<k)<=N;k++)
    for(i=1;i+(1<<k)-1<=N;i++)
    {
        if(h[rmq[i][k-1]]<h[rmq[i+(1<<(k-1))][k-1]])rmq[i][k]=rmq[i][k-1];
        else rmq[i][k]=rmq[i+(1<<(k-1))][k-1];
    }

    for(i=1;i<=m;i++)
    {
        f>>x>>y;
        pz1=first[x];
        pz2=first[y];
        if(pz1>pz2)swap(pz1,pz2);
        k=log2(pz2-pz1+1);

        if(h[rmq[pz1][k]]<h[rmq[pz2-(1<<k)+1][k]])g<<rmq[pz1][k]<<'\n';
        else g<<rmq[pz2-(1<<k)+1][k]<<'\n';
    }
    return 0;
}