Pagini recente » Cod sursa (job #2829163) | Cod sursa (job #3219272) | Cod sursa (job #2557607) | Cod sursa (job #2373580) | Cod sursa (job #2842286)
#include <fstream>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
const int LOG = 18;
const int INF = (1 << 30);
vector<int> fii[N];
int niv[N], st[N], rmq[2 * N][LOG], lg[2 * N];
int p;
void precalc(int n) {
for (int i = 2; i <= n; ++i)
lg[i] = lg[i / 2] + 1;
}
void calc_rmq(int poz, int val) {
rmq[poz][0] = val;
for (int i = 1; i <= lg[poz]; ++i) {
int a = rmq[poz][i - 1];
int b = rmq[poz - (1 << (i - 1))][i - 1];
if (niv[a] < niv[b])
rmq[poz][i] = a;
else
rmq[poz][i] = b;
}
}
void dfs(int nod) {
st[nod] = ++p;
calc_rmq(p, nod);
for (auto f: fii[nod]) {
niv[f] = niv[nod] + 1;
dfs(f);
calc_rmq(++p, nod);
}
}
int lca(int a, int b) {
a = st[a], b = st[b];
if (a > b)
swap(a, b);
int diff = b - a + 1 - (1 << lg[b - a + 1]);
int min1 = rmq[b][lg[b - a + 1]];
int min2 = rmq[b - diff][lg[b - a + 1]];
if (niv[min1] < niv[min2])
return min1;
return min2;
}
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
cin >> n >> q;
for (int i = 2; i <= n; ++i) {
int tata;
cin >> tata;
fii[tata].push_back(i);
}
precalc(2 * n);
niv[0] = INF, niv[1] = 1;
dfs(1);
while (q--) {
int a, b;
cin >> a >> b;
cout << lca(a, b) << "\n";
}
cin.close();
cout.close();
return 0;
}