Cod sursa(job #2183446)

Utilizator flibiaVisanu Cristian flibia Data 23 martie 2018 10:21:58
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include <bits/stdc++.h>
#define N 100100
#define L (pos << 1)
#define R (L | 1)

using namespace std;

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

int n, m, x, y, vf, stk[2 * N], dist[N], pos[N], h[8 * N];
vector <int> v[N];
bitset <N> viz;

void dfs(int tata, int from, int lvl){
	viz[from] = 1;
	stk[++vf] = from;
	pos[from] = vf;
	dist[from] = lvl;
	for(auto to : v[from])
		if(!viz[to]){
			dfs(from, to, lvl + 1);
			stk[++vf] = from;
		}
}

void build(int st, int dr, int pos){
	if(st == dr){
		h[pos] = stk[st];
		return;
	}
	int mid = st + dr >> 1;
	build(st, mid, L);
	build(mid + 1, dr, R);
	h[pos] = (dist[h[L]] < dist[h[R]] ? h[L] : h[R]);
}

int query(int st, int dr, int pos, int l, int r){
	if(l <= st && dr <= r)
		return h[pos];
	int mid = st + dr >> 1;
	int left = 0, right = 0;
	if(l <= mid)
		left = query(st, mid, L, l, r);
	if(r > mid)
		right = query(mid + 1, dr, R, l, r);
	return (dist[left] < dist[right] ? left : right);	
}

int main(){
	in >> n >> m;
	for(int i = 2; i <= n; i++){
		in >> x;
		v[x].push_back(i);
	}
	dfs(0, 1, 1);
	dist[0] = 1e9;
	build(1, vf, 1);
	while(m--){
		in >> x >> y;
		if(pos[x] > pos[y])
			swap(x, y);
	//	cout << pos[x] << ' ' << pos[y] << ' ' << dist[x] << ' ' << dist[y] << endl;
		out << query(1, vf, 1, pos[x], pos[y]) << '\n';
	}
	return 0;
}