Pagini recente » Cod sursa (job #969790) | Cod sursa (job #2688768) | Cod sursa (job #2291413) | Cod sursa (job #1529117) | Cod sursa (job #1622678)
#include <bits/stdc++.h>
using namespace std;
#define pub push_back
const int MAXN = 100010, LOGN = 20;
int n, m;
int father[MAXN], lft[MAXN];
int eR[(MAXN << 4)][LOGN];
vector<int> childs[MAXN], h;
void read() {
assert(freopen("lca.in", "r", stdin));
assert(freopen("lca.out", "w", stdout));
assert(scanf("%d%d", &n, &m));
for(int i = 2; i <= n; ++i) {
assert(scanf("%d", father + i));
childs[father[i]].pub(i);
}
}
void euler(int nod, int niv) {
lft[nod] = h.size();
eR[h.size()][0] = nod;
h.pub(niv);
for(auto child : childs[nod]) {
euler(child, niv + 1);
eR[h.size()][0] = nod;
h.pub(niv);
}
}
void buildRMQ() {
int s = h.size();
for(int j = 1; (1 << j) <= s; ++j) {
for(int i = 0; i + (1 << j) - 1 < s; ++i) {
eR[i][j] = min(eR[i][j-1], eR[i + (1 << (j-1))][j-1]);
}
}
}
int queryRMQ(int a, int b) {
int k = int(log2(b - a + 1));
return min(eR[a][k], eR[b - (1 << k) + 1][k]);
}
int main() {
read();
euler(1, 0);
buildRMQ();
int a, b;
while(m--) {
scanf("%d%d", &a, &b);
a = lft[a]; b = lft[b];
if(a > b)
swap(a, b);
printf("%d\n", queryRMQ(a, b));
}
}