Cod sursa(job #2180395)

Utilizator DimaTCDima Trubca DimaTC Data 20 martie 2018 20:44:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include<bits/stdc++.h>
#define NMAX 100010

using namespace std;

int n,m,a,b,k;
int E[2*NMAX];
int F[NMAX];
int L[2*NMAX];
int rmq[2*NMAX][20];
int LOG[2*100100];
int e;
vector<int>V[NMAX];
void DFS(int x, int pr, int lvl) {
	E[++e]=x;
	L[e]=lvl;
	F[x]=e;
	
	for (int i=0; i<V[x].size(); i++) {
		if (V[x][i]==pr) continue;
		else {
			DFS(V[x][i],x,lvl+1);
			E[++e]=x;
			L[e]=lvl;	
		}
	}
}

int RMQ(int a, int b){
		int l=(b-a+1);
		k=LOG[l];
		if (L[rmq[a][k]]<L[rmq[a+l-(1<<k)][k]]) return E[rmq[a][k]];
		else return E[rmq[a+l-(1<<k)][k]];
}

int main(){
	ifstream cin("lca.in");
	ofstream cout("lca.out");
	cin>>n>>m;
	
	for(int i=1; i<n; i++) { int x;
		cin>>x;
		V[x].push_back(i+1);
	}
	
	E[1]=1;
	DFS(1,-1, 1);
	
	for (int i=2;i<=2*NMAX-5; i++) LOG[i]=LOG[(i>>1)]+1;
	for (int i=1; i<=e; i++) rmq[i][0]=i;
	
	for (int j=1; (1<<j) <e; j++) {
		for (int i=1; i+(1<<j)<=e; i++) {
			if (L[rmq[i][j-1]]>L[rmq[i+(1<<(j-1))][j-1]]) {
				rmq[i][j]=rmq[i+ (1<<(j-1))][j-1];
			} else rmq[i][j]=rmq[i][j-1];
		}
	}
	
	for (int i=1; i<=e; i++) {
	}
	
	while (m--) {
		cin>>a>>b;
		if (F[a]>F[b]) swap(a,b);
		cout<<RMQ(F[a],F[b])<<"\n";
	}
	return 0;
}