Cod sursa(job #3214672)

Utilizator alexlazuLazureanu Alexandru Ioan alexlazu Data 14 martie 2024 12:09:38
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <iostream>
#include <fstream>
#include <math.h>
#include <algorithm>
#include <unordered_map>
#include <set>
#include <vector>
#define infi 999999

using namespace std;

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

#define cin in
#define cout out

const int N = 1e5+1;

int n, m, t[N] , q , sqr[N] , lvl[N];

vector<int> v[N];

int h , rad;

void height(int nod , int parinte ,int level)
{
	h = max(h, level);
	lvl[nod] = level;
	for (auto &i : v[nod])
	{
		if (i != parinte)
		{
			height(i, nod, level + 1);
		}
	}
}

void dfs(int nod, int parinte, int level)
{
	if (level % rad == 0)
	{
		sqr[nod] = nod;
	}
	else
	{
		sqr[nod] = sqr[parinte];
	}
	for (auto& i : v[nod])
	{
		if (i != parinte)
		{
			dfs(i, nod, level + 1);
		}
	}
}

int lca(int p, int r)
{
	while (sqr[p] != sqr[r])
	{
		if (p > r && p != sqr[p])
		{
			p = sqr[t[p]];
		}
		else if(r > p && r!=sqr[r])
		{
			r = sqr[t[r]];
		}
		if (p == sqr[p])
			p = t[p];
		if (r == sqr[r])
			r= t[r];
	}
	while (p != r)
	{
		if (p > r)
			p = t[p];
		else
			r = t[r];
	}
	return p;
}

signed main()
{
	cin >> n >> m;
	for (int i = 2; i <= n; i++)
	{
		cin >> t[i];
		if (i != t[i]) 
		{
			v[i].push_back(t[i]);
			v[t[i]].push_back(i);
		}
	}
	height(1, -1, 0);
	rad = sqrt(h+1);
	dfs(1, -1, 0);
	for (int i = 1 , p , r; i <= m; i++)
	{
		cin >> p >> r;
		cout << lca(p, r) <<'\n';
	}
}