Pagini recente » Borderou de evaluare (job #375958) | Borderou de evaluare (job #588690) | Autentificare | Cod sursa (job #3364064) | Cod sursa (job #3362136)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+1;
long long n, q;
int timp;
int lin[2*N], rmq[20][2*N], lvl[N], lg[2*N], pos[N];
vector<int> mc[N];
bool cmp(int x, int y){
return lvl[x] < lvl[y];
}
void dfs(int nod, int par){
lvl[nod] = lvl[par] + 1;
lin[++timp] = nod;
pos[nod] = timp;
for(auto f : mc[nod]){
dfs(f, nod);
lin[++timp] = nod;
}
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>q;
for(int i=2;i<=n;++i){
int x; cin>>x;
mc[x].push_back(i);
}
dfs(1, 0);
for(int i=1; i <= timp; ++i){
rmq[0][i] = lin[i];
if(i>1){
lg[i] = lg[i/2] + 1;
}
}
for(int e=1; (1<<e)<=timp; ++e){
for(int i=1; i + (1<<(e-1)) + 1<=timp; ++i){
rmq[e][i] = min(rmq[e-1][i], rmq[e-1][i+(1<<(e-1))], cmp);
}
}
while (q--)
{
int x, y;
cin>>x>>y;
x = pos[x];
y = pos[y];
if(x>y){
swap(x, y);
}
int e = lg[y-x+1];
cout << min(rmq[e][x], rmq[e][y-(1<<e)+1], cmp) << '\n';
}
return 0;
}