Pagini recente » Cod sursa (job #1996096) | Cod sursa (job #2357433) | Cod sursa (job #1907013) | Cod sursa (job #628514) | Cod sursa (job #3338463)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define NMAX 100000
#define LOG2 17
vector <int> arb[NMAX + 1];
vector <int> v;
int rmq[LOG2 + 1][NMAX + 1];
int l[NMAX + 1];
int r[NMAX + 1];
int nivel[NMAX + 1];
int lg[2 * NMAX + 1];
int t = 0;
void set_logs(){
lg[0] = lg[1] = 0;
for (int i = 2; i <= NMAX; i++){
lg[i] = lg[i / 2] + 1;
}
}
void dfs(int node){
if (node == 1){
nivel[node] = 1;
}
t++;
l[node] = t;
for (auto neighbour : arb[node]){
v.push_back(node);
nivel[neighbour] = nivel[node] + 1;
dfs(neighbour);
}
v.push_back(node);
t++;
r[node] = t;
}
int e_stramos(int a, int b){
return l[a] <= l[b] && r[b] <= r[a];
}
void range_node(int N){
for (int i = 1; i < N; i++){
rmq[0][i] = v[i];
}
for (int p = 1; p <= lg[N]; p++){
for (int i = 1; i + (1 << p) - 1 < N; i++){
int p1 = rmq[p - 1][i];
int p2 = rmq[p - 1][i + (1 << (p - 1)) - 1];
if (nivel[p1] < nivel[p2]){
rmq[p][i] = p1;
}
else{
rmq[p][i] = p2;
}
}
}
}
int lca(int a, int b){
if (nivel[a] < nivel[b]){
return a;
}
return b;
}
int main()
{
v.push_back(0);
ios::sync_with_stdio(false);
fin.tie(nullptr);
fout.tie(nullptr);
set_logs();
int N, Q;
fin >> N >> Q;
for (int i = 1; i < N; i++){
int x;
fin >> x;
arb[x].push_back(i + 1);
}
dfs(1);
range_node(v.size());
for (int i = 1; i <= Q; i++){
int a, b;
fin >> a >> b;
int dist = lg[r[b] - l[a] + 1];
if (l[a] <= r[b] && r[b] <= r[a]){
fout << a << " ";
}
else if (l[b] <= l[a] && r[a] <= r[b]){
fout << b << " ";
}
else{
fout << lca(rmq[dist][l[a] - 1], rmq[dist][r[b] - (1 << dist) + 2]) << '\n';
}
}
return 0;
}