Cod sursa(job #2773625)

Utilizator Stefan4814Voicila Stefan Stefan4814 Data 8 septembrie 2021 00:15:54
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include <bits/stdc++.h>
#define NMAX 100001
#define MMAX 2000001

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

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

struct node {
	int euler, level;
}nodes[MMAX];

int k;
void dfs(int vertex, int depth) {
	nodes[++k].euler = vertex;
	nodes[k].level = depth;
	first[vertex] = k;

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

void gen() {
	int log = log_2[k];
	for(int i = 1; i <= k; i++)
		dp[i][0] = i;

	for(int i = 1; i <= log; i++) {
		for(int j = 1; j <= k; j++) {
			if(j + (1 << i) > k)
				break;

			if(nodes[dp[j][i - 1]].level <= nodes[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 get(int left, int right) {
	if(left > right)
		swap(left, right);

	int dist = right - left + 1;
	if(nodes[dp[left][log_2[dist]]].level <= nodes[dp[right - (1 << log_2[dist]) + 1][log_2[dist]]].level)
		return nodes[dp[left][log_2[dist]]].euler;
	return nodes[dp[right - (1 << log_2[dist]) + 1][log_2[dist]]].euler;
}

int main() {
	int n, m;
	fin >> n >> m;

    for(int i = 2; i <= MMAX - 1; i++)
		log_2[i] = log_2[i / 2]+1;

	for(int i = 2; i <= n; i++) {
		int x;
		fin >> x;
		graph[x].push_back(i);
	}
	dfs(1, 0);
	gen();
	for(int i = 1; i <= m; i++) {
		int a, b;
		fin >> a >> b;
		fout << get(first[a], first[b]) << '\n';
	}
}