Cod sursa(job #2728994)

Utilizator UnknownPercentageBuca Mihnea-Vicentiu UnknownPercentage Data 23 martie 2021 22:30:11
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
#include <bits/stdc++.h>
 
using namespace std;
 
ifstream f("lca.in");
ofstream g("lca.out");

vector <int> Gr[100001];

bitset <100001> visited;

int st[200003][20];
int Euler[200001], Height[100001], first[100001], Log[200001];
int N, M, len;

void dfs(int v, int h = 0){
	visited[v] = 1;
	Height[v] = h;
	Euler[++len] = v;
	first[v] = len;
	for(int to : Gr[v])
		if(!visited[to]){
			dfs(to, h + 1);
			Euler[++len] = v;
		}
}

void rmq(){
	N = len;
    for(int i = 2;i <= N;i++)
        Log[i] = Log[i / 2] + 1;

    for(int i = 1;i <= N;i++)
        st[i][0] = Euler[i];
 
    int K = Log[N];
    for(int j = 1;j <= K;j++)
        for(int i = 1;i + (1 << j) <= N + 1;i++){
            st[i][j] = st[i][j - 1];
            if(Height[st[i + (1 << (j - 1))][j - 1]] < Height[st[i][j]])
            	st[i][j] = st[i + (1 << (j - 1))][j - 1];
        }
}

void lca(int u, int v){
	int L = first[u], R = first[v];
    if (L > R)
        swap(L, R);

    int j = Log[R - L + 1];
    if(Height[st[L][j]] < Height[st[R - (1 << j) + 1][j]])
    	g << st[L][j] << "\n";
    else 
    	g << st[R - (1 << j) + 1][j] << "\n";
}

int main(){

	f >> N >> M;
	for(int i = 2, x;i <= N;i++){
		f >> x;
		Gr[x].emplace_back(i);
	}

	dfs(1);
	rmq();

	while(M--){
		int u, v;
		f >> u >> v;
		lca(u, v);
	}
}