Cod sursa(job #2738406)

Utilizator AndreiD31Dragan Andrei AndreiD31 Data 5 aprilie 2021 19:55:12
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
#include <bits/stdc++.h>

using namespace std;

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

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

void build_arbore(int nod)
{
    viz[nod]=1;
    for(int i=0;i<v[nod].size();i++)
    {
        int vecin=v[nod][i];
        if(viz[vecin]==0)
        {
            V[nod].push_back(vecin);
            build_arbore(vecin);
        }
    }
}

void parcurgere_euler(int nod)
{
    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];
        h[vecin]=h[nod]+1;
        parcurgere_euler(vecin);

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

int n,m,i,N,k,x,y,pz1,pz2,lca,nivel_curent,nivel_lca,t,nr_stramos,tata[100100],rmq[300100][20],stramos[100100][20];
int main()
{
    f>>n>>m;
    for(i=2;i<=n;i++)
    {
        f>>x;
        v[x].push_back(i);
        v[i].push_back(x);

        tata[i]=x;
    }

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

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

    for(i=2;i<=n;i++)stramos[i][0]=tata[i];

    for(k=1;(1<<k)<=n;k++)
    for(i=1;i<=n;i++)
        stramos[i][k]=stramos[stramos[i][k-1]][k-1];

    for(k=1;(1<<k)<=N;k++)
    for(i=1;i+(1<<k)-1<=N;i++)
        rmq[i][k]=min(rmq[i][k-1],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);

        nivel_lca=min(rmq[pz1][k],rmq[pz2-(1<<k)+1][k]);
        nivel_curent=h[x];

        nr_stramos=nivel_curent-nivel_lca;
        t=0;lca=x;
        while(nr_stramos)
        {
            if(nr_stramos%2==1)lca=stramos[lca][t];
            t++;
            nr_stramos/=2;
        }

        g<<lca<<'\n';
    }
    return 0;
}