Pagini recente » Cod sursa (job #1165459) | Cod sursa (job #2440507) | Cod sursa (job #208262) | Cod sursa (job #978482) | Cod sursa (job #2115381)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout("lca.out");
const int N_MAX = 500005;
vector<int> vec[N_MAX];
int eu[N_MAX], niv[N_MAX], ne, n, m, a, b, poz[N_MAX];
int dp[30][N_MAX];
void euler(int nod, int nivel){
eu[++ne] = nod;
niv[ne] = nivel;
poz[nod] = ne;
for(auto v : vec[nod]){
euler(v, nivel + 1);
eu[++ne] = nod;
niv[ne] = nivel;
}
}
void init(){
for(int i = 1; i<=ne; ++i)
dp[0][i] = i;
for(int power = 1; (1 << power) <= ne; ++power)
for(int i = 1; i + (1 <<power) - 1 <= ne; ++i)
if(niv[dp[power-1][i]] < niv[dp[power-1][i + (1<<(power-1))]])
dp[power][i] = dp[power-1][i];
else
dp[power][i] = dp[power-1][i + (1<<(power-1))];
}
int rmq(int lo, int hi){
int power = log2(hi - lo + 1);
if(niv[dp[power][lo]] < niv[dp[power][hi - (1 << power) + 1]])
return dp[power][lo];
return dp[power][hi - (1 << power) + 1];
}
int query(int a, int b){
int lo = min(a,b);
int hi = max(a,b);
return eu[rmq(lo, hi)];
}
int main(){
fin >> n >> m;
for(int i = 2, nr; i<=n; ++i){
fin >> nr; vec[nr].push_back(i);
}
euler(1, 0);
init();
while(m--){
fin >> a >> b;
fout << query(poz[a],poz[b]) << "\n";
}
return 0;
}
//Andrei Muntean, 2018