Cod sursa(job #605968)

Utilizator alexeiIacob Radu alexei Data 2 august 2011 23:57:54
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.01 kb
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<vector>
#include<deque>
#include<set>

#define NMAX 100010
#define logN 20

using namespace std;

vector< int > G[NMAX];
int E[NMAX<<1],P[NMAX];
int RMQ[logN][NMAX<<2];
int L[NMAX<<1];
bool viz[NMAX];

int N;

void euler( int nod,int level )
{
    viz[nod]=1;
    E[ ++E[0] ]=nod;
    L[ E[0] ]=level;
    P[ nod ]=E[0];
	
    int i,v;
    for(i=0; i<(signed)G[nod].size(); ++i)
    {
        v=G[nod][i];
        if( !viz[v] )
        {
            euler(v,level+1);
	    E[++E[0]]=nod;
            L[E[0]]=level;
        }
    }
}

int PW2[NMAX<<1];

void pw2()
{
    int i;
    for(i=2; i<(NMAX<<1); ++i)
        PW2[i]=PW2[i>>1]+1;
}

void rmq()
{
    int i,j;
    int N=E[0];
    for(i=1; i<=N; ++i)
        RMQ[0][i]=i;

    for(i=1; (1<<i)<N; ++i)
    {
        for(j=1; j<=N-(1<<i); ++j)
        {
            if( L[RMQ[i-1][j]]<L[RMQ[i-1][j+(1<<(i-1))]])
                RMQ[i][j]=RMQ[i-1][j];
            else
                RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
        }
    }

}

int query( int nod1, int nod2 )
{
    int p1=P[nod1];
    int p2=P[nod2];
    if( p2<p1 )
    {
	p1^=p2;p2^=p1;p1^=p2;
    }

    int diff=p2-p1+1;
    int d=PW2[diff];
    int sh=diff-(1<<d);

    if( L[ RMQ[d][p1] ] < L[ RMQ[d][p1+sh] ] )
    {
		return E[ RMQ[d][p1] ];
	}
	else
	{
		return E[ RMQ[d][ p1+sh ] ];
	}
}

void DF(int nod)
{
    viz[nod]=0;
    int i,v;
    for(i=0; i<(signed)G[nod].size(); ++i)
    {
        v=G[nod][i];
        if( L[P[v]]>L[P[nod]] && viz[v] )
            DF(v);
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

	int N,M;
	scanf("%d%d\n",&N,&M);

	int i,a1;
	for(i=2; i<=N; ++i)
	{
		scanf("%d",&a1);
		G[a1].push_back(i);
		G[i].push_back(a1);
	}

	pw2();
	euler(1,1);
	rmq();

	int a2;
	for(i=1; i<=M; ++i)
	{
		scanf("%d%d\n",&a1,&a2);
		printf("%d\n",query(a1,a2));
	}

    return 0;
}