Pagini recente » Cod sursa (job #2786067) | Cod sursa (job #1235103) | Cod sursa (job #2774157) | Cod sursa (job #2585672) | Cod sursa (job #1910970)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#define NMAX 100001
#define LOGMAX 18
#define NE (unsigned)((1<<31) + 1)
using namespace std;
unsigned n, m, maxH = 0, impartire;
unsigned T[NMAX], H[NMAX];
unsigned lg[NMAX];
vector<vector<unsigned>> tatiLog;
unsigned Tsqrt[NMAX];
vector<unsigned> Copchi[NMAX];
unsigned lcaLG(unsigned i, unsigned j) {
if (H[i] < H[j]) {
swap(i, j);
}
for (unsigned k = lg[H[i] + 1]; H[i] != H[j]; --k) {
if (H[tatiLog[k][i]] >= H[j]) {
i = tatiLog[k][i];
}
if (!k) {
break;
}
}
if (i == j) {
return i + 1;
}
for (unsigned k = lg[H[i] + 1]; T[i] != T[j]; --k) {
if (tatiLog[k][i] != NE && tatiLog[k][i] != tatiLog[k][j]) {
i = tatiLog[k][i];
j = tatiLog[k][j];
}
if (!k) {
break;
}
}
return T[i] + 1;
}
void solveLG() {
unsigned i, j;
while (m--) {
cin >> i >> j;
cout << lcaLG(i - 1, j - 1) << '\n';
}
}
void preprocessLG() {
tatiLog.push_back(vector<unsigned>(n));
tatiLog[0][0] = NE;
for (unsigned i = 1; i < n; ++i) {
tatiLog[0][i] = T[i];
}
for (unsigned j = 1; (unsigned)(1 << j) <= maxH; ++j) {
tatiLog.push_back(vector<unsigned>(n, NE));
for (unsigned i = 0; i < n; ++i) {
if (tatiLog[j-1][i] != NE) { // echivalent cu H[i] - (1<<(j-1)) >= 0
tatiLog[j][i] = tatiLog[j-1][tatiLog[j-1][i]];
}
}
}
lg[1] = 0;
for (unsigned i = 2; i <= maxH; ++i) {
lg[i] = lg[i >> 1] + 1;
}
}
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 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();
preprocessLG();
solveLG();
return 0;
}