Cod sursa(job #978993)

Utilizator ZoranZomboratZoran Zomborat Goran ZoranZomborat Data 30 iulie 2013 23:42:34
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include<vector>
#include<iostream>
#include<fstream>
using namespace std;
#define N_MAX 100005
int n,m,k,euler[N_MAX<<1],level[N_MAX<<1],first[N_MAX],rmq[18][N_MAX<<1],power[N_MAX<<1];
vector <int> g[N_MAX];
ifstream fin("lca.in");
ofstream fout("lca.out");	
void citire()
{
fin>>n>>m;
for(int i=2;i<=n;i++)
	{int x;
	fin>>x;
	g[x].push_back(i);}
}
void DFS(int nod,int niv)
{
    vector<int> :: iterator it;
    euler[++k]=nod;
    level[k]=niv;
    first[nod]=k;
    for(it=g[nod].begin();it!=g[nod].end();it++)
    {
        DFS(*it,niv+1);
        euler[++k]=nod;
        level[k]=niv;
    }
}
void RMQ()
{
int i,j,l;
power[1]=0;
for(i=2;i<=k;i++)
	power[i]=power[i>>1]+1;
for(i=1;i<=k;i++)
	rmq[0][i]=i;
for(i=1;(1<<i)<=k;i++)
	for(j=1;j<=k-(1<<i);j++)
	{
	l=1<<(i-1);	
	if(level[rmq[i-1][j]]>level[rmq[i-1][j+l]])
		rmq[i][j]=rmq[i-1][j+l];
	else
		rmq[i][j]=rmq[i-1][j];
	}
}
void LCA(int x,int y)
{
int dif,plus,sol,q;
int a=first[x], b=first[y];
if(a>b)
	swap(a,b);
dif=b-a+1;
q=power[dif];
plus=dif-(1<<q);
if(level[rmq[q][a]]>level[rmq[q][a+plus]])
	sol=euler[rmq[q][a+plus]];
else
	sol=euler[rmq[q][a]];
fout<<sol<<endl;
}
int main()
{
citire();
DFS(1,0);
RMQ();
for(int i=m;i!=0;i--)
{int x,y;
fin>>x>>y;
LCA(x,y);
}
}