Pagini recente » Monitorul de evaluare | Cod sursa (job #2460167) | Cod sursa (job #1730885) | Cod sursa (job #1776035) | Cod sursa (job #2675433)
#include <bits/stdc++.h>
#define MAX 200005
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, k;
int t[MAX], h[MAX], e[MAX], lg[MAX],first[MAX], rmq[20][MAX];
bitset < MAX > c;
void Euler(int nod, int lvl){
e[++k] = nod;
h[k] = lvl;
first[nod] = k;
c[nod] = true;
for(int i = 1; i <= n; i++)
if(!c[i] && t[i] == nod){
Euler(i, lvl + 1);
h[++k] = lvl;
e[k] = nod;
}
}
void RMQ(){
for(int i = 2; i <= k; i++)
lg[i] = lg[i / 2] + 1;
for(int j = 1; j <= k; j++)
rmq[0][j] = j;
for(int i = 1; (1 << i) <= k; i++)
for(int j = 1; j <= k - (1 << i) + 1; j++){
int col = (1 << (i - 1));
rmq[i][j] = rmq[i - 1][j];
if(h[rmq[i - 1][j + col]] < h[rmq[i][j]])
rmq[i][j] = rmq[i - 1][j + col];
}
}
int main(){
in>>n>>m;
for(int i = 2; i <= n; i++)
in>>t[i];
Euler(1, 0);
RMQ();
while(m--){
int x, y;
in>>x>>y;
x = first[x], y = first[y];
if(y < x)
x ^= y, y ^= x, x ^= y;
int dif = y - x + 1;
int lin = lg[dif];
int col = dif - (1 << lin);
int minim = rmq[lin][x];
if(h[minim] > h[rmq[lin][x + col]])
minim = rmq[lin][x + col];
out<<e[minim]<<"\n";
}
}