Cod sursa(job #2154370)

Utilizator dumitrescu_andreiDumitrescu Andrei dumitrescu_andrei Data 6 martie 2018 21:44:38
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 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[2000005];
vector <int> V[100005];
bool viz[100005];

void DFS(int x,int nivel)
{
    viz[x]=1;
    indice++;
    levels[indice] = nivel;
    euler[indice] = x;
    if(aparitie[x]==-1)
        aparitie[x]=indice;
    for(int i=0;i<V[x].size();++i)
        if(!viz[V[x][i]])
    {
        DFS(V[x][i],nivel+1);
        indice++;
        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-start)/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];

}

int RMQ(int start, int stop, int left, int right, int poz)
{
    if(left<= start && stop<=right)
        return arb[poz];

    if(stop < left || start > right)
        return -1;

    int mid = start + (stop-start)/2;
    int q1,q2;
    q1=RMQ(start,mid,left,right,2*poz);
    q2=RMQ(mid+1,stop,left,right,2*poz+1);

    if(q1==-1)
        return q2;
    else if(q2 == -1)
        return q1;
    if(levels[q1]<levels[q2])
        return q1;
    else
        return q2;

}

int main()
{
    f>>n>>m;
    for(int i=1;i<n;++i)
    {
        int tata;
        f>>tata;
        V[i+1].push_back(tata);
        V[tata].push_back(i+1);
    }
    memset(aparitie,-1,sizeof(aparitie));
    DFS(1,1);
    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);
        int pozitie;
        pozitie = RMQ(1,indice,aparitie[x],aparitie[y],1);
        g<<euler[pozitie]<<'\n';
    }
}