Cod sursa(job #2748610)

Utilizator osoagentOso Agent osoagent Data 1 mai 2021 20:38:36
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.13 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<typename T>
using oset = tree<T, null_type, less<T>,
				  rb_tree_tag, tree_order_statistics_node_update>;

#ifdef Wi_TEST
	template<typename T1, typename T2>
	ostream& operator<<(ostream& out, pair<T1,T2> p) {
		out << "(" << p.first << ", " << p.second << ")";
		out.flush();
		return out;
	}
	#define deb(x) cout << #x << " = " << x << endl;
#else
	#define deb(x)
	#define cin fin
	#define cout fout
#endif

#define N 100005

pair<int, int> aint[4*N];

void update(int nod, int st, int dr, int poz, pair<int, int>& val) {
	if(st == dr)
		aint[nod] = val;
	else {
		int mij = (st + dr) >> 1;
		if(poz <= mij)
			update(nod*2, st, mij, poz, val);
		else
			update(nod*2+1, mij+1, dr, poz, val);
		
		if(aint[nod*2].second < aint[nod*2+1].second) {
			aint[nod] = aint[nod*2];
		} else {
			aint[nod] = aint[nod*2+1];
		}
	}
}

pair<int, int> query(int nod, int st, int dr, int l, int r) {
	if(l <= st && dr <= r)
		return aint[nod];
	else {
		int mij = (st + dr) >> 1;
		pair<int, int> rez{-1, -1}, aux;
		if(l <= mij)
			rez = query(2*nod, st, mij, l, r);
		if(r > mij) {
			aux = query(2*nod+1, mij+1, dr, l, r);
			if(rez.first == -1)
				rez = aux;
			else {
				if(rez.second > aux.second)
					rez = aux;
			}
		}
		return rez;
	}
}

vector<int> gc[N];
vector< pair<int, int> > rez;
int fiof[N];

void DFS(int x, int lvl = 0) {
	rez.push_back({x, lvl});
	for(int& aux : gc[x]) {
		DFS(aux, lvl+1);
		rez.push_back({x, lvl});		
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	
	ifstream fin("lca.in");
	ofstream fout("lca.out");
	
	int n, m, x;
	cin >> n >> m;
	
	for(int i = 2; i <= n; ++i){
		cin >> x;
		gc[x].push_back(i);
	}
	
	DFS(1);
	
	for(int i = 0; i < rez.size(); ++i) {
		update(1, 1, 2*n-1, i, rez[i]);
		if(!fiof[rez[i].first])
			fiof[rez[i].first] = i;
		// deb(rez[i]);
		// deb(fiof[rez[i].first]);
	}
	fiof[1] = 0;
	
	while(m--) {
		int a, b;
		cin >> a >> b;
		a = fiof[a];
		b = fiof[b];
		if(a > b) swap(a, b);
		cout << query(1, 1, 2*n-1, a, b).first << '\n';
	}
	return 0;
}