Cod sursa(job #2876010)

Utilizator ViAlexVisan Alexandru ViAlex Data 22 martie 2022 20:37:59
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.45 kb
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;


ifstream in("lca.in");
ofstream out("lca.out");

const int mx=2e5;

int n,q;

struct node{
	int index,depth;
};

int lg2[mx],first[mx];
node rmq[20][mx];
vector<int> g[mx];
vector<node> euler;

void build_rmq(){
	unsigned len=euler.size();

	lg2[1]=0;
	for(int i=2;i<mx;i++){
		lg2[i]=lg2[i/2]+1;	
	}

	for(int i=0;i<len;i++){
		rmq[0][i]=euler[i];
	}

	for(int k=1;(1<<k)<=len;k++){
		int now=(1<<k),old=(1<<(k-1));

		for(int j=0;j<=len-now;j++){
			node a=rmq[k-1][j],b=rmq[k-1][j+old];
			rmq[k][j]=(a.depth<b.depth) ? a: b;
		}
	}
}

node query_rmq(int l, int r){
	if(l>r){
		swap(l,r);
	}
	int distance=(r-l+1);
	int chunk=lg2[distance];
	int chunk_size=1<<chunk;

	node a=rmq[chunk][l];
	node b=rmq[chunk][r-chunk_size+1];

	return a.depth<b.depth?a:b;
}


void read(){
	in>>n>>q;
	int father;
	for(int i=2;i<=n;i++){
		in>>father;
		g[father].push_back(i);
		g[i].push_back(father);
	}
}

void dfs(int node,int father,int depth){

	for(int k:g[node]){
		if(k==father)
			continue;
		euler.push_back({node,depth});
		dfs(k,node,depth+1);
	}

	euler.push_back({node,depth});
}

void solve(){
	dfs(1,0,0);	
	
	for(int i=0;i<mx;i++){
		first[i]=-1;
	}

	for(int i=0;i<euler.size();i++){
		if(first[euler[i].index]==-1){
			first[euler[i].index]=i;
		}
	}
	build_rmq();

	int a,b;
	while(q--){
		in>>a>>b;
		out<<query_rmq(first[a],first[b]).index<<'\n';
	}

}

int main(){
	read();
	solve();

	return 0;
}