Cod sursa(job #2002845)

Utilizator vendettaSalajan Razvan vendetta Data 20 iulie 2017 22:26:49
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

const int nmax = 1e5 + 5;
const int logmax = 18;
int n, m;
vector<int> gf[nmax];
int viz[nmax], nivel[nmax], ancestors[logmax][nmax];

void dfs(int node) {
	viz[node] = 1;
	for (int i = 0; i < gf[node].size(); ++i) {
		int vc = gf[node][i];
		if (viz[vc] == 0) {
			ancestors[0][vc] = node;
			nivel[vc] = nivel[node] + 1;
			dfs(vc);
		}
	}
}

void preprocessForLca() {
	nivel[1] = 1;
	dfs(1);
	for (int i = 1; i < logmax; ++i) {
		for (int j = 1; j <= n; ++j) {
			int previousAncestor = ancestors[i - 1][j];
			ancestors[i][j] = ancestors[i - 1][previousAncestor];
		}
	}
}

void bringToLevel(int &node, int toLevel) {
	int dist = nivel[node] - toLevel;
	for (int i = logmax - 1; i >= 0; --i) {
		if ((dist & (1 << i)) > 0 ) {
			node = ancestors[i][node];
		}
	}

}

int getLca(int x, int y) {
	//nivel [x] > nivel[y];
	if (nivel[x] < nivel[y]) {
		swap(x, y);
	}
	bringToLevel(x, nivel[y]);
	if (x == y) {
		return x;
	}
	for (int i = logmax - 1; i >= 0; --i) {
		if (ancestors[i][x] == 0 || ancestors[i][y] == 0) {
			assert(ancestors[i][x] == ancestors[i][y]);
			continue;
		}
		if (ancestors[i][x] == ancestors[i][y]) {
			continue;
		}
		x = ancestors[i][x];
		y = ancestors[i][y];
	}
	int lca = ancestors[0][x];
	assert(lca >= 1 && lca <= n);
	return lca;

}

int main() {
	ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
	// freopen("test.in", "r", stdin);
	// freopen("test.out", "w", stdout);
	//freopen("test.err", "w", stderr);
#endif

	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);

	cin >> n >> m;
	for (int i = 1; i < n; ++i) {
		int x, y;
		// cin >> x >> y;
		int xx; cin >> xx;
		x = xx;
		y = i + 1;
		gf[x].pb(y);
		gf[y].pb(x);
	}

	preprocessForLca();

	for (int i = 1; i <= m; ++i) {
		int x, y;
		cin >> x >> y;
		cout << getLca(x, y) << "\n";
	}

	return 0;
}