Cod sursa(job #2639657)

Utilizator KlinashkaDiacicov Calin Marian Klinashka Data 3 august 2020 13:30:03
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.38 kb
#include <bits/stdc++.h>
using namespace std;

const int NMAX=(int)1e5;
bool vis[NMAX+1];
int first[NMAX+1];
vector<int> adj[NMAX+1];
vector<pair<int, int>> euler;
int minint[3*NMAX+1][19];


void rmq() {
	for(int i=0;i<euler.size();++i) {
		minint[i][0]=i;
	}
	for(int j=1;(1<<j)<=(int)euler.size();++j) {
		for(int i=0;i+(1<<j)-1<(int)euler.size();++i) {
			if(euler[minint[i][j-1]].second<euler[minint[i+(1<<(j-1))][j-1]].second)
				minint[i][j]=minint[i][j-1];
			else
				minint[i][j]=minint[i+(1<<(j-1))][j-1];
		}
	}
}

void dfs(int a, int lev=0) {
	first[a]=(int)euler.size();
	euler.push_back(make_pair(a, lev));
	vis[a]=1;
	for(auto b:adj[a]) {
		if(vis[b]==0) {
			dfs(b, lev+1);
			euler.push_back(make_pair(a, lev));
		}
	}
}

int min_query(int st, int dr) {
	int k=(int)log2(dr-st+1);
	int idx;
	if(euler[minint[st][k]].second<euler[minint[dr-(1<<k)+1][k]].second)
		idx=minint[st][k];
	else
		idx=minint[dr-(1<<k)+1][k];
	return euler[idx].first;
}

int main() {
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	int N, M;
	scanf("%d %d", &N, &M);
	for(int i=2;i<=N;++i) {
		int x;
		scanf("%d", &x);
		adj[x].push_back(i);
	}
	dfs(1);
	rmq();

	for(int i=1;i<=M;++i) {
		int x, y;
		scanf("%d %d", &x, &y);
		x=first[x];
		y=first[y];
		if(y<x)
			swap(x, y);
		printf("%d\n", min_query(x, y));
	}

	return 0;
}