Cod sursa(job #2632702)

Utilizator xCata02Catalin Brita xCata02 Data 4 iulie 2020 13:59:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <bits/stdc++.h>
using namespace std;

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

#define cin  fin
#define cout fout

 
#define endl "\n"
#define ll long long
 	
pair < int ,int > rmq[18][200002];
int logaritmi[200002];

vector < int > g[100002];
vector < int > euler;

int level[100002];
int poz[100002];

void DFS(int nod, int lvl) {
	poz[nod] = euler.size();
	level[nod] = lvl;
	euler.push_back(nod);
	for(auto it : g[nod]) {
		DFS(it, lvl++);
		euler.push_back(nod);
	}
}

void makeEuler() {
	euler.push_back(0);
	DFS(1, 1);
}
 
void initRMQ() {
	int n = euler.size();
    logaritmi[1] = 0;
    for(int i=2; i <= n; i++) {
        logaritmi[i] = logaritmi[i / 2] + 1;
    }
    
    for(int i=1; i <= n; i++) {
		rmq[0][i] = {level[euler[i]], euler[i]};
	}
 
    for(int lungime = 1; (1 << lungime) <=n; lungime++) {
        for(int el = 1; el <= n - (1 << (lungime)); el++) {
            rmq[lungime][el] = min(rmq[lungime - 1][el], rmq[lungime - 1][el + (1 << (lungime - 1))]);
        }
    }
}

void calculate(int a, int b) {
    int interval = b - a + 1;
    int lungime  = logaritmi[interval];
    cout << min(rmq[lungime][a].second, rmq[lungime][a + interval - (1 << lungime)].second) << endl;
}

 
void solve() {
	int n, m;
	cin >> n >> m;
	for(int i=2; i <= n; i++) {
		int x; cin >> x;
		g[x].push_back(i);
	}
	makeEuler();
	initRMQ();
	
	while(m--) {
		int a, b;
		cin >> a >> b;
		calculate(min(poz[a], poz[b]), max(poz[a], poz[b]));
	}
}
 
 
int main() {
	ios_base::sync_with_stdio(0);
	cin .tie(0);
	cout.tie(0);
	
	int testCases = 1;
	//cin >> testCases;
	while(testCases--) {
		solve();
	}
}