Cod sursa(job #2510519)

Utilizator HumikoPostu Alexandru Humiko Data 16 decembrie 2019 20:31:24
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.64 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");

static const int NMAX = 1e5+5;

//LCA CU STRAMOSI, (faster than RMQ XDDDDD AYY LOL)

int n, m;

int Log2[NMAX];
int level[NMAX];
int dp[16][NMAX];

vector <int> graph[NMAX];

void dfs (int vertex, int depth) {
	level[vertex] = depth;

	for ( auto x:graph[vertex] ) {
		if ( !level[x] ) {
			dfs(x, depth+1);
		}
	}
}

int goUp (int vertex, int dif) {
	for ( int i = 0; i <= Log2[dif]; ++i ) {
		if ( dif&(1<<i) ) {
			vertex = dp[i][vertex];
		}
	}

	return vertex;
}

int LCA (int a, int b) {
	if ( level[a] > level[b] ) {
		swap(a, b);
	}

	int dif = level[b]-level[a];
	b = goUp(b, dif);

	if ( a == b ) {
		return a;
	}

	for ( int i = Log2[n]; i >= 0; --i ) {
		if ( dp[i][a] != dp[i][b] && dp[i][a] && dp[i][b] ) {
			a = dp[i][a];
			b = dp[i][b];
		}
	}

	return dp[0][a];
}

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

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

	cin>>n>>m;

	dp[0][1] = 1;

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

	dfs(1, 1);

	for ( int i = 1; i <= Log2[n]; ++i ) {
		for ( int j = 1; j <= n; ++j ) {
			dp[i][j] = dp[i-1][dp[i-1][j]];
		}
	}

	while ( m-- ) {
		int a, b;
		cin>>a>>b;

		cout<<LCA(a, b)<<'\n';
	}
}