Cod sursa(job #2097991)

Utilizator sandupetrascoPetrasco Sandu sandupetrasco Data 1 ianuarie 2018 23:38:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#include <bits/stdc++.h>

#define pb push_back 
#define x first 
#define y second 
#define MOD 1000000007

using namespace std;
typedef long long ll;
typedef pair< int , int > PII;
const int dirx[] = {-2,-1,1,2, 1, -1};
const int diry[] = {0,1,1,0, -1, -1};
inline void debugMode() {
    #ifndef ONLINE_JUDGE
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    #endif
}

int n, m, RMQ[19][1 << 19], F[1 << 17];
vector < int > L[100100], E;

void make_Euler(int x, int fath){
	E.pb(x);
	for (auto it : L[x]){
		if (it != fath){
			make_Euler(it, x);
			E.pb(x);
		}
	}
}

int main(){
	debugMode();
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for (int i = 1, x; i < n; i++){
		cin >> x;
		L[x].pb(i + 1);
	}
	
	make_Euler(1, 1);
	
	int n = E.size();

	for (int i = 1; i <= n; i++){
		RMQ[0][i] = E[i - 1];
		if (!F[E[i - 1]]) F[E[i - 1]] = i; 
	}

	for (int i = 1; (1 << i) <= n; i++){
		for (int j = 1; j + (1 << (i - 1)) <= n; j++){
			RMQ[i][j] = min(RMQ[i - 1][j], RMQ[i - 1][j + (1 << (i - 1))]);
		}
	}

	for (int i = 1, x, y; i <= m; i++){
		cin >> x >> y;
		x = F[x]; y = F[y];
		if (x > y) swap(x, y);
		int diff = (y - x + 1);
		int k = log2(diff);
		cout << min(RMQ[k][x], RMQ[k][y - (1 << k) + 1]) << "\n";
	}

	
	return 0;
}