Cod sursa(job #3259291)

Utilizator andystarzSuna Andrei andystarz Data 25 noiembrie 2024 17:46:12
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <iostream>
#include <vector>

using namespace std;
vector<int>v[100005];
int papi[100005];
int tin[100005];
int tout[100005];
bool seen[100005];
int height[100005];
int cnt=0;
int scroll[300005];
int rmq[300005][20];
void dysfunction(int nod)
{
	scroll[++cnt]=nod;
	rmq[cnt][0]=nod;
	//cout<<rmq[cnt][0]<<" ";
	tin[nod]=cnt;
	tout[nod]=cnt;
	for (auto i : v[nod])
	{
		dysfunction(i);
		scroll[++cnt]=nod;
		rmq[cnt][0]=nod;
		//cout<<rmq[cnt][0]<<" ";
		tout[nod]=cnt;
	}
	return;
}
void build()
{
	for (int bit=1; bit<20; bit++)
	{
		for (int j=1; j<=cnt+1-(1<<bit); j++)
		{
			if (height[rmq[j][bit-1]]<height[rmq[j+(1<<(bit-1))][bit-1]])
			rmq[j][bit]=rmq[j][bit-1];
			else
			rmq[j][bit]=rmq[j+(1<<(bit-1))][bit-1];
			//rmq[j][bit]=min(rmq[j][bit-1], rmq[j+(1<<(bit-1))][bit-1]);
			//cout<<rmq[j][bit]<<" ";
		}
		//cout<<'\n';
	}
	return;
}
int skib[300005];
int deeznuts(int a, int b)
{
	if (height[a]<=height[b])
		return a;
	return b;
}
void skibidi()
{
	int put=0;
	for (int i=1; i<=300000; i++)
	{
		skib[i]=put;
		if ((1<<(put+1))<=(i+1))
			put++;
	}
	//31 - __builtin_clz(x);
	return;
}
int main()
{
    int n, q, a;
	cin>>n>>q;
	height[1]=1;
	for (int i=2; i<=n; i++)
	{
		cin>>a;
		v[a].push_back(i);
		papi[i]=a;
		height[i]=1+height[papi[i]];
	}
	dysfunction(1);
	build();
	skibidi();
	int b, l, r;
	for (int i=1; i<=q; i++)
	{
		cin>>a>>b;
		l=min(tin[a], tin[b]);
		r=max(tout[a], tout[b]);
		cout<<deeznuts(rmq[l][skib[r-l+1]], rmq[r-(1<<(skib[r-l+1]))+1][skib[r-l+1]])<<'\n';
	}
}