Cod sursa(job #673841)

Utilizator R.A.RFMI Romila Remus Arthur R.A.R Data 4 februarie 2012 22:57:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>
#define nmax 100004

using namespace std;

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


vector<int> G[nmax];
int Op,N,NM;

int Lg[nmax*2],Poz[nmax*2];
int  V[nmax*2];
int RMQ[18][2*nmax];

inline int _min(int a,int b){if(a<b)return a;return b;}

void DF(int nod)
{
    int i;
    V[++NM] = nod;
    Poz[nod] = NM;
    for(i=0;i<G[nod].size();i++)
    {
        DF(G[nod][i]);
        V[++NM] = nod;
    }

}

int LCA(int a,int b)    //return RMQ(Poz[a],Poz[b]);
{
    int x = Poz[a],y = Poz[b];
    if(x>y)x^=y^=x^=y;
    int nivel,diferenta;
    nivel = Lg[y-x+1];
    diferenta = y-x+1-(1<<nivel);
    return _min(RMQ[nivel][x],RMQ[nivel][x+diferenta]);

}

int main()
{
    int x,y,i,j;
    in>>N>>Op;
    for(i=2;i<=N;i++)
    {
        in>>x;
        G[x].push_back(i);
    }
    //reprezentare EULER
    DF(1);

    //RMQ
    Lg[1] = 0;
    for(i=2;i<=NM;i++)Lg[i]=Lg[i/2]+1;
    for(i=1;i<=NM;i++)RMQ[0][i]=V[i];
    for(i=1;(1<<i)<=NM;++i)
    {
        for(j=1;j<=NM-(1<<i)+1;j++)
        {
            RMQ[i][j] = _min(RMQ[i-1][j],RMQ[i-1][j+(1<<i-1)]);
        }
    }

    while(Op--)
    {
        in>>x>>y;
        //afisez cel mai apropiat stramos comun
        out<<LCA(x,y)<<'\n';
    }
    return 0;
}