Pagini recente » Cod sursa (job #3148424) | Cod sursa (job #1857517) | Cod sursa (job #722596) | Cod sursa (job #2770906) | Cod sursa (job #1910717)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#define NMAX 100001
using namespace std;
unsigned n, m, maxH = 0, impartire;
unsigned T[NMAX], H[NMAX];
unsigned Tsqrt[NMAX];
//vector<unsigned> Copchi[NMAX];
unsigned lcaSQRT(unsigned i, unsigned j) {
while (Tsqrt[i] != Tsqrt[j]) {
if (H[i] > H[j]) {
i = Tsqrt[i];
} else {
j = Tsqrt[j];
}
}
while (i != j) {
if (H[i] > H[j]) {
i = T[i];
} else {
j = T[j];
}
}
return i + 1;
}
void solveSQRT() {
unsigned i, j;
while (m--) {
cin >> i >> j;
cout << lcaSQRT(i - 1, j - 1) << '\n';
}
}
void preprocessLG() {
}
void preprocessSQRT() {
for (unsigned i = 0; i < n; ++i) {
unsigned lev = H[i] / impartire;
unsigned tatal = T[i];
lev = lev < 1 ? lev : lev - 1;
while (H[tatal] / impartire != lev) {
tatal = T[tatal];
}
Tsqrt[i] = tatal;
}
}
//void dfsSQRT(unsigned nod, unsigned tatal) {
// if (!(H[nod] % impartire)) {
// tatal = T[nod];
// }
//
// Tsqrt[nod] = tatal;
//
// for (auto it : Copchi[nod]) {
// dfsSQRT(it, tatal);
// }
//}
unsigned inaltime(unsigned nod) {
if (nod == 0) {
return 0;
}
if (!H[T[nod]]) {
return inaltime(T[nod]) + 1;
}
return H[T[nod]] + 1;
}
void inaltime() {
for (unsigned i = 0; i < n; ++i) {
H[i] = inaltime(i);
maxH = max(maxH, H[i]);
}
impartire = sqrt(maxH);
}
void read() {
unsigned tatal;
cin >> n >> m;
T[0] = 0;
H[0] = 0;
for (unsigned i = 1; i < n; ++i) {
cin >> tatal;
--tatal;
T[i] = tatal;
//Copchi[tatal].push_back(i);
}
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
read();
inaltime();
preprocessSQRT();
//dfsSQRT(0, 0);
solveSQRT();
return 0;
}