Cod sursa(job #1410049)

Utilizator Arodoet96Teodora Stoleru Arodoet96 Data 30 martie 2015 20:27:04
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include <fstream>
#include <vector>
#define DMAX 100004

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n, m;
vector <int> fii[DMAX];
int euler[DMAX*4], lge;
int first[DMAX], nivel[DMAX];
int rmq[DMAX*4][20], log[DMAX];

void citire();
void parcurgere_euler(int nod);
void RMQ();
void logaritm();
void query();

int main()
{
    citire();
    parcurgere_euler(1);
    RMQ();
    logaritm();
    query();
    return 0;
}

void citire()
{
    int i, tata;
    fin>>n>>m;
    for(i=2;i<=n;++i)
    {
        fin>>tata;
        fii[tata].push_back(i);
    }
}

void parcurgere_euler(int nod)
{
    int i, lg, v;

    //euler[++lge]=nod;
    first[nod]=++lge;

    rmq[lge][0]=nod;

    lg=fii[nod].size();
    for(i=0;i<lg;++i)
    {
        v=fii[nod][i];
        nivel[v]=nivel[nod]+1;
        parcurgere_euler(v);

        //euler[++lge]=nod;
        rmq[++lge][0]=nod;
    }
}

void RMQ()
{
    int i, j, L;
    for(j=1;(1<<j)<=lge;++j)
        for(i=1;i<=lge-(1<<j)+1;++i)
        {
            L=(1<<(j-1));
            if(nivel[rmq[i][j-1]]<nivel[rmq[i+L][j-1]]) rmq[i][j]=rmq[i][j-1];
                else rmq[i][j]=rmq[i+L][j-1];
        }
}

void logaritm()
{
    int i;
    for(i=2;i<=lge;++i)
        log[i]=log[i/2]+1;
}

void query()
{
    int i, x, y, aux, dif, L, l;
    for(i=1;i<=m;++i)
    {
        fin>>x>>y;

        x=first[x]; y=first[y];

        if(y<x) { aux=x; x=y; y=aux; }

        dif=y-x+1;
        L=log[dif];
        l=dif-(1<<L);

        if(nivel[rmq[x][L]]<nivel[rmq[x+l][L]]) fout<<rmq[x][L]<<'\n';
            else fout<<rmq[x+l][L]<<'\n';
    }
}