Cod sursa(job #3129600)

Utilizator Dobricean_IoanDobricean Ionut Dobricean_Ioan Data 15 mai 2023 09:00:59
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.16 kb
#include <fstream>
#include <vector>


using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int Dim =1e5 + 5;
vector<int>g[Dim];
int euler[Dim * 2],cnt,viz[Dim],rmq[18][Dim],poz[Dim];
int nivel[Dim*2],lg[Dim*2];

void dfs(int x){
	
	euler[++cnt] = x;
	poz[x] = cnt;
	for(auto y : g[x]){
		if(!viz[y])	
			{
				nivel[y] = nivel[x] + 1;
				dfs(y);
				euler[++cnt] = x;
			}
	}
}

void RMQ(){
	
	lg[2] = 1;
	for(int i = 3; i <= cnt; ++i)
		lg[i] = lg[i/2]+1;
	for(int i = 1; i <= cnt;++i)
		rmq[0][i] = euler[i];
		
	for(int pw = 1; pw <= lg[cnt]; ++pw)
		for(int i = 1; i <= cnt- (1<<(pw-1)); ++i)
			if(nivel[rmq[pw-1][i]] < nivel[rmq[pw-1][i+(1<<(pw-1))]])
				rmq[pw][i] = rmq[pw-1][i];
			else
				rmq[pw][i] = rmq[pw-1][i+(1<<(pw-1))];
	
}

int lca(int x, int y){
	
	 x = poz[x];
	y = poz[y];
	int pw = lg[y-x+1];
	if(nivel[rmq[pw][x]] < nivel[rmq[pw][y-(1<<pw)+1]])
		return rmq[pw][x];
	else
		return rmq[pw][y-(1<<pw)+1];
}



int main()
{
	int n,m;
	  	fin >> n >> m;
	for ( int i = 2,x,y; i <= n; ++i) {
		fin >> y;
		g[y].push_back(i);
	}
	dfs(1);

	RMQ();
	for (int x,y; m > 0; --m) {
		fin >> x >> y;
		fout << lca(x,y) << "\n";
	}
        return 0;
}