Cod sursa(job #3309162)

Utilizator CosminaneBoac Mihai Cosmin Cosminane Data 1 septembrie 2025 22:33:50
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int tata[100005], h[100005], tot_fii[100005], lant[100005], h_lant[100005], dp[100005][5], lant_curent;
vector <int> fii[100005];
void dfs1( int x ){
	int i, y;
	for( i = 0; i < fii[x].size(); i++ ){
		y = fii[x][i];
		h[y] = h[x] + 1;
		dfs1( y );
		tot_fii[x] += tot_fii[y];
	}
	tot_fii[x]++;
}
void dfs2( int x ){
	int i, y, max_fii, r;
	max_fii = r = -1;
	for( i = 0; i < fii[x].size(); i++ ){
		y = fii[x][i];
		if( tot_fii[y] > max_fii ){
			max_fii = tot_fii[y];
			r = y;
		}
	}
	if( r != -1 ){
		lant[r] = lant_curent;
		dfs2( r );
		for( i = 0; i < fii[x].size(); i++ ){
			y = fii[x][i];
			if( y != r ){
				lant_curent++;
				h_lant[lant_curent] = h_lant[lant[x]] + 1;
				dp[lant_curent][0] = x;
				lant[y] = lant_curent;
				dfs2( y );
			}
		}
	}
}
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 >> tata[i];
		fii[tata[i]].push_back( i );
	}
	tata[1] = 1;
	dfs1( 1 );
	lant_curent = 0;
	lant[1] = 0;
	dfs2( 1 );
	/*for( i = 1; i <= n; i++ ){
		cout << i << ' ' << lant[i] << '\n';
	}*/
	for( i = 1; i < 5; i++ ){
		for( j = 0; j <= lant_curent; j++ ){
			dp[j][i] = dp[lant[dp[j][i - 1]]][i - 1];
			//cout << i << ' ' << j << ' ' << dp[j][i] << '\n';
		}
	}
	for( i = 0; i < m; i++ ){
		fin >> x >> y;
		//cout << x << ' ' << y << ' ' << lant[x] << ' ' << lant[y] << '\n';
		if( h_lant[lant[x]] < h_lant[lant[y]] ){
			swap( x, y );
		}
		for( j = 4; j >= 0; j-- ){
			if( h_lant[lant[x]] - ( 1 << j ) >= h_lant[lant[y]] ){
				x = dp[lant[x]][j];
			}
		}
		//cout << x << ' ' << y << ' ' << lant[x] << ' ' << lant[y] << '\n';
		if( lant[x] != lant[y] ){
			for( j = 4; j >= 0; j-- ){
				if( h_lant[lant[x]] - ( 1 << j ) >= 0 && h_lant[lant[dp[lant[x]][j]]] != h_lant[lant[dp[lant[y]][j]]] ){
					x = dp[lant[x]][j];
					y = dp[lant[y]][j];
				}
				//cout << x << ' ' << y << ' ' << lant[x] << ' ' << lant[y] << '\n';
			}
			//cout << "INTRAT\n";
			x = dp[lant[x]][0];
			y = dp[lant[y]][0];
		}
		//cout << x << ' ' << y << ' ' << lant[x] << ' ' << lant[y] << '\n';
		if( h[x] < h[y] ){
			fout << x << '\n';
		}
		else{
			fout << y << '\n';
		}
		//cout << '\n';
	}
	return 0;
}