Pagini recente » Cod sursa (job #1818481) | Cod sursa (job #962150) | Cod sursa (job #358698) | Cod sursa (job #270031) | Cod sursa (job #3263379)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, queries;
vector <int> graph[200005];
vector <pair <int,int>> arr;
int rmq[200005][20], idx[200005], power[200005];
void euler (int x, int predecesor, int level){
arr.push_back({x, level});
if (idx[x] == -1)
idx[x] = arr.size()-1;
for (auto idx:graph[x])
if (idx != predecesor){
euler(idx, x, level+1);
arr.push_back({x, level});
}
}
void buildRmq (){
for (int i=0; i<arr.size(); ++i)
rmq[i][0] = i; // tin minte indicii (am nevoie de noduri dar trebuie sa compar dupa height)
for (int j=1; j<17; ++j){
for (int i=0; i<arr.size(); ++i){
if (arr[rmq[i][j-1]].second < arr[rmq[i+(1<<(j-1))][j-1]].second) // compar dupa level
rmq[i][j] = rmq[i][j-1];
else
rmq[i][j] = rmq[i+(1<<(j-1))][j-1];
}
}
}
void BuildPower2 (){
power[1] = 0;
for (int i=2; i<arr.size(); ++i){
if (i > 1<<(power[i-1]+1)){
power[i] = power[i-1]+1;
}
else
power[i] = power[i-1];
}
}
int query (int x, int y){
if (arr[rmq[x][power[y-x+1]]].second < arr[rmq[y-power[y-x+1]+1][power[y-x+1]]].second)
return arr[rmq[x][power[y-x+1]]].first;
else
return arr[rmq[y-power[y-x+1]+1][power[y-x+1]]].first;
}
int main (){
int x, y;
in >> n >> queries;
for (int i=1; i<n; ++i){
in >> x;
graph[x].push_back(i+1);
graph[i+1].push_back(x);
}
for (int i=1; i<=n; ++i)
idx[i] = -1;
euler (1, 0, 1);
buildRmq();
BuildPower2();
// for (int i=0; i<arr.size(); ++i)
// cout << i << ' ';
// cout << '\n';
// for (int i=0; i<arr.size(); ++i)
// cout << arr[i].first << ' ';
// cout << '\n';
// for (int i=0; i<arr.size(); ++i)
// cout << arr[i].second << ' ';
// cout << '\n';
for (; queries; --queries){
in >> x >> y;
if (idx[x] > idx[y])
swap (x,y);
out << query(idx[x], idx[y]) << '\n';
}
return 0;
}