Cod sursa(job #2081699)

Utilizator Andrei243Nitu Mandel Andrei Andrei243 Data 4 decembrie 2017 23:43:52
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.87 kb
//#include <iostream>
#include <vector>
#include <fstream>
//#include <stdlib.h>

using namespace std;
int n,nrop;
int nivel[100000];
int log2[200000];
int primaaparitie[100100];
int pozitie_e, euler[200000];
vector <int> arbore[100100];
int RMQ[200100][20];
ifstream in("lca.in");
ofstream out("lca.out");



int nivel_min(int a,int b)
{
    if(nivel[a]<nivel[b])return a;
    return b;
}



void generare_euler(int n)
{
    primaaparitie[n]=pozitie_e;
    euler[pozitie_e]=n;
    pozitie_e++;
    if(arbore[n].size()>0)
    {
        for(unsigned int i=0; i<arbore[n].size(); i++)
        {
            generare_euler(arbore[n][i]);
            euler[pozitie_e]=n;
    pozitie_e++;

        }
    }
}


void rmq()
{
    for(unsigned int i=0; i<pozitie_e; i++)
    {
        RMQ[i][0]=euler[i];
    }
    for(unsigned int i=1; (1<<i)<pozitie_e; i++)
    {
        for(unsigned int j=0; (1<<i)+j<pozitie_e; j++)
        {
            RMQ[j][i]=nivel_min(RMQ[j][i-1],RMQ[j+(1<<(i-1))][i-1]);
        }
    }
}

void logaritmare()
{
    for(int i=2; i<=pozitie_e; i++)log2[i]=log2[i/2]+1;


}


int calcul_minim(int a,int b)
{
    int diferenta=b-a+1;
    int pow=log2[diferenta];
    int rest=diferenta-(1<<pow);
    return nivel_min(RMQ[a][pow],RMQ[a+rest][pow]);

}

int main()
{
    //log2[1]=0;
    //nivel[0]=0;
    in>>n>>nrop;


    int x;


    for(int i=1; i<n; i++)
    {
        in>>x;
        arbore[x-1].push_back(i);
        nivel[i]=nivel[x-1]+1;

    }
    generare_euler(0);
    logaritmare();
    rmq();
    for(int i=0; i<nrop; i++)
    {
        int a,b;
        in>>a>>b;
        a--;b--;
        if(primaaparitie[a]>primaaparitie[b])
    {
        a=a^b;
        b=a^b;
        a=a^b;
    }
    out<<calcul_minim(primaaparitie[a],primaaparitie[b])+1<<endl;

    }

    return 0;
}