Cod sursa(job #1446000)

Utilizator radu_cebotariRadu Cebotari radu_cebotari Data 31 mai 2015 18:02:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.42 kb
#include<fstream>
#include<vector>
#include<iostream>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX = 100005;
const int LMAX = 20;

vector<int> arb[NMAX];
int v[4*NMAX],H[4*NMAX],First[NMAX],n,m,K,R[LMAX][4*NMAX],lg[4*NMAX];

void read()
{

    in>>n>>m;
    int x;
    for(int i = 1;  i < n ; ++i){
        in>>x;
        arb[x].push_back(i+1);
    }

}

void dfs(int nod,int level)
{

    v[++K] = nod;
    H[K] = level;
    First[nod] = K;
    for(int i = 0 ; i < arb[nod].size() ; ++i){
        dfs(arb[nod][i],level + 1);
        v[++K] = nod;
        H[K] = level;
    }

}

void rmq()
{

    lg[1] = 0;
    for(int i = 2 ; i <= K ; ++i)
        lg[i] = lg[i/2] + 1;

    for(int i = 1 ; i <= K ; ++i)
        R[0][i] = i;

    for(int i = 1 ; i <= lg[K] ; ++i)
        for(int j = 1 ; j <= K - (1 << i) + 1 ; ++j)
            if(H[R[i-1][j]] <= H[R[i-1][j + (1 << (i-1))]])
                R[i][j] = R[i-1][j];
            else
                R[i][j] = R[i-1][j + (1 << (i-1))];

}

int query(int a,int b)
{

    a = First[a];
    b = First[b];
    if(a > b)
        swap(a,b);
    int len = b - a + 1;
    int k = lg[len];
    int dif = len - (1 << k);
    if(H[R[k][a]] <= H[R[k][a + dif]])
        return v[R[k][a]];
    return v[R[k][a + dif]];
}

int main()
{

    read();
    dfs(1,0);
    rmq();
    int a,b;
    for( ; m ; --m){
        in>>a>>b;
        out<<query(a,b)<<"\n";
    }
    return 0;
}