Pagini recente » Cod sursa (job #1623156) | Cod sursa (job #2487090) | Cod sursa (job #2554946) | Cod sursa (job #1607554) | Cod sursa (job #2432567)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 10 * 1e4 + 15;
const int LOGMAX = 25;
const int INF = 1e8;
int dist[MAXN], first[MAXN], euler[2 * MAXN], rmq[LOGMAX][2 * MAXN], lg[MAXN], lung;
///cel de-al i-lea număr reprezentând tatăl nodului i+1
vector <int> g[MAXN];
ifstream fin("lca.in");
ofstream fout("lca.out");
void buildLOG(){
for(int i = 0; i < lung; ++i)
rmq[0][i] = euler[i];
for(int i = 2; i <= lung; ++i)
lg[i] = lg[i / 2] + 1;
}
void buildEuler(int node, int papa){
euler[++lung] = node;
first[node] = lung;
dist[node] = dist[papa] + 1;
for(auto y : g[node]){
if(y != papa) {
buildEuler(y, node);
euler[++lung] = node;
}
}
}
void buildRMQ(){
for(int i = 1; (1 << i) < lung; ++i){
for(int j = 0; j + (1 << i) - 1 < lung; ++j){
if(dist[rmq[i - 1][j]] <= dist[rmq[i - 1][j + (1 << (i - 1))]])
rmq[i][j] = rmq[i - 1][j];
else rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
}
int lca(int x, int y){
int st = first[x];
int dr = first[y];
if(st > dr) swap(st, dr);
int logaritm = lg[dr - st + 1];
if(dist[rmq[logaritm][st]] <= dist[rmq[logaritm][dr - (1 << logaritm) + 1]])
return rmq[logaritm][st];
return rmq[logaritm][dr - (1 << logaritm) + 1];
}
int main(){
int n , m; fin >> n >> m;
for(int i = 0; i < n - 1; ++i){
int x; fin >> x;
g[x].push_back(i + 2);
}
buildEuler(1, 0);
buildLOG();
buildRMQ();
for(int i = 1; i <= m; ++i){
int x, y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
return 0;
}