Cod sursa(job #2504475)

Utilizator HumikoPostu Alexandru Humiko Data 4 decembrie 2019 22:39:57
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 kb
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <cstring>

using namespace std;

//#include <iostream>
#include <fstream>

//ifstream cin ("input.in");
//ofstream cout ("output.out");

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

struct node {
	int euler, level;
};

static const int NMAX = 1e5+5;
static const int MMAX = 2e6+5;

int logar[MMAX];
int firstEuler[MMAX];

node v[MMAX];

int dp[MMAX][25];
vector <int> graph[NMAX];

int k;

void dfs(int vertex, int depth) {
	v[++k] = {vertex, depth};
	firstEuler[vertex] = k;

	for ( auto x:graph[vertex] ) {
		dfs(x, depth+1);
		v[++k] = {vertex, depth};
	}
}

void genRMQ () {
	int K = logar[k];

	for ( int i = 1; i <= k; ++i ) {
		dp[i][0] = (v[i].level <= v[i+1].level ? i : i+1 );
	}

	for ( int i = 1; i <= K; ++i ) {
		for ( int j = 1; j <= k; ++j ) {
			if ( j+(1<<i) > k ) {
				continue;
			}

			if ( v[dp[j][i-1]].level <= v[dp[j+(1<<(i-1))][i-1]].level ) {
				dp[j][i] = dp[j][i-1];
			} 
			else {
				dp[j][i] = dp[j+(1<<(i-1))][i-1];
			}
		}
	}
}

int getRMQ (int l, int r) {
	if ( l > r ) {
		swap(l, r);
	}

	int dist = r-l+1;

	if ( v[dp[l][logar[dist]]].level <= v[dp[r-logar[dist]][logar[dist]]].level ) {
		return v[dp[l][logar[dist]]].euler;
	}

	return v[dp[r-logar[dist]][logar[dist]]].euler;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	for ( int i = 2; i <= NMAX-5; ++i ) {
		logar[i] = logar[i/2]+1;
	}

	int n, m;
	cin>>n>>m;

	for ( int i = 2; i <= n; ++i ) {
		int x;
		cin>>x;
		graph[x].push_back(i);
	}

	dfs(1, 0);
	genRMQ();

	for ( int i = 1; i <= m; ++i ) {
		int a, b;
		cin>>a>>b;

		cout<<getRMQ(firstEuler[a], firstEuler[b])<<'\n';
	}
}