Cod sursa(job #3274264)

Utilizator CosminaneBoac Mihai Cosmin Cosminane Data 5 februarie 2025 22:36:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
struct elem{
	int x, nivel;
};
int rmq[300005][20], logar[300005], first[100005];
vector <int> v[100005];
vector <elem> euler;
void dfs( int x, int nivel ){
	int i;
	euler.push_back( { x, nivel } );
	first[x] = euler.size() - 1;
	for( i = 0; i < v[x].size(); i++ ){
		dfs( v[x][i], nivel + 1 );
		euler.push_back( { x, nivel } );
	}
}
int lca(int x, int y){
	int l, a, b;
	//cout << x << ' ' << y << ' ';
	x = first[x];
	y = first[y];
	if( x > y ){
		swap( x, y );
	}
	//cout << x << ' ' << y << '\n';
	l = logar[y - x + 1];
	a = rmq[x][l];
	b = rmq[y - ( 1 << l ) + 1][l];
	if( euler[a].nivel < euler[b].nivel ){
		return euler[a].x;
	}
	return euler[b].x;
}
int main(){
	int n, m, i, j, x, y;
	ifstream fin( "lca.in" );
	ofstream fout( "lca.out" );
	fin >> n >> m;
	for( i = 2; i <= n; i++ ){
		fin >> x;
		v[x].push_back( i );
	}
	dfs( 1, 0 );
	for( i = 0; i < euler.size(); i++ ){
		rmq[i][0] = i;
	}
	for( i = 1; ( 1 << i ) <= euler.size(); i++ ){
		for( j = 0; j + ( 1 << i ) - 1 < euler.size(); j++ ){
			x = rmq[j][i - 1];
			y = rmq[j + ( 1 << ( i - 1 ) )][i - 1];
			if( euler[x].nivel < euler[y].nivel ){
				rmq[j][i] = x;
			}
			else{
				rmq[j][i] = y;
			}
			//cout << j << ' ' << ( 1 << i ) << ' ' << euler[rmq[j][i]].x << '\n';
		}
	}
	logar[0] = logar[1] = 0;
	for( i = 2; i < euler.size(); i++ ){
		logar[i] = logar[i / 2] + 1;
		//cout << euler[i].x << ' ' << euler[i].nivel << '\n';
	}
	for( i = 0; i < m; i++ ){
		fin >> x >> y;
		fout << lca( x, y ) << '\n';
	}
	return 0;
}