Cod sursa(job #1537859)

Utilizator Andrei66Andrei Rusu Andrei66 Data 28 noiembrie 2015 11:10:14
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include <bits/stdc++.h>

// #define x first
// #define y second
#define VM 100005
#define pb push_back
#define ppb pop_back
#define ll long long
#define pii pair<int, int>

using namespace std;

//don't forget to put input in the file!!!
ifstream fin("lca.in");
ofstream fout("lca.out");

int n, m, euler[VM], first[VM], logg[VM], rmq[18][VM], nod[18][VM], lev[VM], cnt = 0;
vector<int> g[VM];

void dfs(int x){
	euler[++cnt] = x;
	first[x] = cnt;
	for(int i=0; i<g[x].size(); ++i){
		lev[g[x][i]] = lev[x] + 1;
		dfs(g[x][i]);
		euler[++cnt] = x;
	}
}

int lca(int x, int y){
	x = first[x];
	y = first[y];
	if(x > y)	swap(x, y);
	int dif = y - x + 1;
	int p = logg[dif];
	if(rmq[p][x] < rmq[p][y - (1<<p) + 1])	return nod[p][x];
	return nod[p][y - (1<<p) + 1];
}

int main(){
	fin>>n>>m;
	for(int a, i=1; i<n; ++i){
		fin>>a;
		g[a].pb(i + 1);
	}

	dfs(1);

	for(int i=2; i<=cnt; ++i)	logg[i] = logg[i / 2] + 1;
	for(int i=1; i<=cnt; ++i){
		rmq[0][i] = lev[euler[i]];
		nod[0][i] = euler[i];
	}

	for(int i=1; (1<<i) <= cnt; ++i)
		for(int j=1; j + (1<<i) - 1 <= cnt; ++j)
			if(rmq[i-1][j] < rmq[i-1][j + (1<<(i-1))]){
				rmq[i][j] = rmq[i-1][j];
				nod[i][j] = nod[i-1][j];
			}
			else{
				rmq[i][j] = rmq[i-1][j + (1<<(i-1))];
				nod[i][j] = nod[i-1][j + (1<<(i-1))];
			}

	for(int a, b, i=1; i<=m; ++i){
		fin>>a>>b;
		fout<<lca(a, b)<<'\n';
	}

	return 0;
}