Cod sursa(job #2303377)

Utilizator cezar.plescaCezar Plesca cezar.plesca Data 16 decembrie 2018 10:39:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include<stdio.h>

#include<iostream>
#include<fstream>

#include<vector>
using namespace std;

#define MAXN 100000
vector<int> L[MAXN+1];
#define MAXM 2000000

int M,N;

typedef struct pereche{
	int value;
	int idxarb;
}pereche;

pereche INDEX[MAXM];
int PTR[MAXN+1];
int lung;

void buildIndex(int nod,int level){
	if(L[nod].empty()){
		INDEX[lung].value=level;
		INDEX[lung].idxarb=nod;
		PTR[nod]=lung;
		lung++;
		return;
	}
	vector<int>::iterator it;
	for(it=L[nod].begin();it!=L[nod].end();it++){
		buildIndex(*it,level+1);
		INDEX[lung].value=level;
		INDEX[lung].idxarb=nod;
		PTR[nod]=lung;
		lung++;
	}
}

#define MAXLOGM 21
int MINI[MAXM][MAXLOGM];

void buildtable(){
	for(int i=0;i<lung;i++)
		MINI[i][0]=i;
	int l=0,p=1;
	while(p<=lung){
		p*=2; l++;
	}
	int min1,min2;
	p=1;
	for(int j=1;j<l;j++){
		p*=2;
		for(int i=0;i<lung;i++){
			min1=MINI[i][j-1];
			if((i+p/2)<lung){
				min2=MINI[i+p/2][j-1];
				if(INDEX[min1].value<INDEX[min2].value)
					MINI[i][j]=min1;
				else
					MINI[i][j]=min2;
			}
			else
				MINI[i][j]=min1;
		}
	}
}

int findmin(int i,int j){
	if(i>j){
		int temp=i;
		i=j;
		j=temp;
	}
	int l=0,p=1;
	while((i+p-1)<=j){
		l++; p*=2;
	}
	int min1=MINI[i][l-1];
	int min2=MINI[j-p/2+1][l-1];
	if(INDEX[min1].value<INDEX[min2].value)
		return min1;
	else
		return min2;	
}

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

	scanf("%d %d", &N,&M);
	
	int parent;
	for(int i=1;i<N;i++){
		scanf("%d", &parent);
		L[parent].push_back(i+1);
	}

	buildIndex(1,0);

	buildtable();

	int x,y,rez;
	for(int i=0;i<M;i++){
		scanf("%d %d",&x,&y);
		rez=findmin(PTR[x],PTR[y]);
		printf("%d\n",INDEX[rez].idxarb);
	}
	
	return 0;
}