Cod sursa(job #1617654)

Utilizator vasica38Vasile Catana vasica38 Data 27 februarie 2016 15:41:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include<fstream>
using namespace std;


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


typedef struct lista
{
	int info;
	lista * next;
} *nod;
nod a[2*100123];

void add(int x, nod &p)
{
	nod r = new lista;
	r->info = x;
	r->next = p;
	p = r;
}
int min(int a, int b) { return (a < b) ? (a) : (b); }


int i, j, m, n;
int h[2*100123];
int e[2*100123];
int poz[2*100123];
bool viz[100123];
int u;


void dfs(int x, int k)
{
	//viz[x] = 1;
	e[++u] = x;
	h[u] = k;
	poz[x] = u;
	for (nod r = a[x]; r; r = r->next)
	{
	    dfs(r->info,k+1);
		e[++u] = x;
		h[u] = k;
	}
}
int lg[200001];
int rmq[2*100123][21];



void Rmq()
{
	for (int i = 2; i <= u; ++i) lg[i] = lg[i / 2] + 1;
	for (int i = 1; i <= u; ++i) rmq[i][0] = i;
	for (int j = 1; (1 << j) <= u; ++j){
		for (int i = 1; i + (1 << j) - 1 <= u; ++i)
		{
			rmq[i][j] = rmq[i][j - 1];
			if (h[rmq[i][j - 1]] > h[rmq[i + (1 << (j-1))][j - 1]]) rmq[i][j] = rmq[i + (1 << (j-1))][j - 1];
		}
	}
}

int max(int a, int b) { return (a > b) ? (a) : (b); }

int LCA(int x, int y)
{
	x = poz[x];
	y = poz[y];
	if (x > y) swap(x, y);
	int lgg = lg[y - x + 1];
	return (h[rmq[x][lgg]] < h[rmq[y - (1 << lgg) + 1][lgg]]) ? e[rmq[x][lgg]] : e[rmq[y - (1 << lgg) + 1][lgg]];
}




int main()
{
	//cout << max(1, 2);
	cin >> n >> m;
	ios_base::sync_with_stdio(0);
	for (int i = 2; i <= n; ++i)
	{
		int x;
		cin >> x;
		add(i, a[x]);
	}
	dfs(1, 0);
	Rmq();
//	cout << u << "\n";
	while (m--)
	{
		int x, y;
		cin >> x >> y;
	//	cout << x <<" " <<y<<"\n";
		cout << LCA(x, y)<< "\n";
	}

	return 0;
}