Cod sursa(job #2731175)

Utilizator Mihai_EduardMihai Eduard Mihai_Eduard Data 27 martie 2021 14:16:01
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.23 kb
#include <vector>
#include <fstream>

#define NMAX 1000001

using namespace std;

ifstream fin ("ski.in");
ofstream fout ("ski.out");

int n, m, K;
int L[2*NMAX], H[2*NMAX], Lg[2*NMAX], First[NMAX];
int Rmq[25][4*NMAX];

vector <int> g[NMAX];

void citire()
{
	fin>>n>>m;
	int x;
	for(int i=2;i<=n;i++)
    {
        fin>>x;
        g[x].push_back(i);
    }
}

void dfs(int nod, int lev)
{
	H[++K]=nod;
	L[K]=lev;
	First[nod]=K;
	for(unsigned int i=0;i<g[nod].size();i++)
    {
        dfs(g[nod][i],lev+1);
        H[++K]=nod;
		L[K]=lev;
    }
}

void rmq()
{
	for(int i=2;i<=K;i++)
		Lg[i]=Lg[i/2]+1;

	for(int i=1;i<=K;i++)
		Rmq[0][i]=i;

	for(int i=1;(1<<i)<K;i++)
		for(int j=1;j<=K-(1<<i);j++)
		{
			int l=1<<(i-1);

			Rmq[i][j]=Rmq[i-1][j];
			if(L[Rmq[i-1][j+l]]<L[Rmq[i][j]])
				Rmq[i][j]=Rmq[i-1][j+l];
		}
}

int lca(int x, int y)
{
	int diff, l, sol, sh;
	int a=First[x], b=First[y];
	if(a>b)
        swap(a,b);
	diff=b-a+1;
	l=Lg[diff];
	sol=Rmq[l][a];
	sh=diff-(1<<l);
	if(L[sol]>L[Rmq[l][a+sh]])
		sol=Rmq[l][a+sh];
	return H[sol];
}

int main()
{
	citire();
	dfs(1, 0);
	rmq();

	while(m--)
	{
		int x, y;
		fin>>x>>y;
		fout<<lca(x, y)<<'\n';
	}
}