Cod sursa(job #2154357)

Utilizator dumitrescu_andreiDumitrescu Andrei dumitrescu_andrei Data 6 martie 2018 21:29:46
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <bits/stdc++.h>
using namespace std;

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


int n,indice,m,levels[200005],euler[200005],aparitie[100005],arb[200005],sol1,sol2;
vector <int> V[100005];


void DFS(int x,int nivel)
{
    levels[++indice] = nivel;
    euler[indice] = x;
    aparitie[x]=indice;
    for(int i=0;i<V[x].size();++i)
    {
        DFS(V[x][i],nivel+1);
        levels[++indice] = nivel;
        euler[indice] = x;
    }

}

void creeare(int start, int stop, int poz)
{
    if(start == stop)
    {
        arb[poz] = start;
        return;
    }

    int mid = (start+stop)/2;

    creeare(start,mid,2*poz);
    creeare(mid+1,stop,2*poz + 1);

    if(levels[arb[2*poz]]<=levels[arb[2*poz+1]])
        arb[poz]=arb[2*poz];
    else
        arb[poz]=arb[2*poz+1];

}

void RMQ(int start, int stop, int left, int right, int poz)
{
    if(left<= start && stop<=right)
        {
            if(levels[arb[poz]]<sol1)
            {
                sol1=levels[arb[poz]];
                sol2=euler[arb[poz]];
            }
            return;
        }

    int mid = (start+stop)/2;
    if(left<=mid) RMQ(start,mid,left,right,2*poz);
    if(right>mid) RMQ(mid+1,stop,left,right,2*poz+1);


}

int main()
{
    f>>n>>m;
    for(int i=2;i<=n;++i)
    {
        int tata;
        f>>tata;
        V[tata].push_back(i);
    }
    memset(aparitie,-1,sizeof(aparitie));
    DFS(1,0);
    creeare(1,indice,1);


    for(int i=1;i<=m;++i)
    {
        int x,y;
        f>>x>>y;
        if(aparitie[x]>aparitie[y])
            swap(x,y);
        sol1=sol2=0x3f3f3f3f;
        RMQ(1,indice,aparitie[x],aparitie[y],1);
        g<<sol2<<'\n';
    }
}