Pagini recente » Cod sursa (job #2458562) | Diferente pentru olimpici intre reviziile 180 si 127 | Cod sursa (job #2128340) | Atasamentele paginii Clasament eusebiuoji2019cls9 | Cod sursa (job #3174544)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, tata[100001], viz[100001], nr, euler[100001], nivel[100001], pozitie[100001];
int minim, raspuns;
vector <int> g[100001];
struct {
int a, b;
} aint[5000006];
void parcurgere (int start, int p) {
viz[start] = 1;
nivel[start] = p;
euler[++nr] = start;
pozitie[start] = nr;
for (int i : g[start]) {
if (!viz[i]) {
parcurgere(i, p + 1);
nr++;
}
euler[nr] = start;
pozitie[start] = nr;
nivel[start] = p;
}
}
void build (int nod, int left, int right) {
if (left == right) {
aint[nod].a = nivel[euler[left]];
aint[nod].b = euler[left];
return;
}
int middle = (left + right) / 2;
build(2 * nod, left, middle);
build(2 * nod + 1, middle + 1, right);
if (aint[2 * nod].a < aint[2 * nod + 1].a) {
aint[nod].a = aint[2 * nod].a;
aint[nod].b = aint[2 * nod].b;
} else {
aint[nod].a = aint[2 * nod + 1].a;
aint[nod].b = aint[2 * nod + 1]. b;
}
}
void query (int nod, int left, int right, int stanga, int dreapta) {
if (stanga <= left && dreapta >= right) {
if (aint[nod].a <= minim) {
minim = aint[nod].a;
raspuns = aint[nod].b;
}
return;
}
int middle = (left + right) / 2;
if (stanga <= middle) {
query(2 * nod, left, middle, stanga, dreapta);
}
if (dreapta > middle) {
query(2 * nod + 1, middle + 1, right, stanga, dreapta);
}
}
int main () {
fin >> n >> m;
for (int i = 2; i <= n; i++) {
fin >> tata[i];
g[i].push_back(tata[i]);
g[tata[i]].push_back(i);
}
parcurgere(1, 1);
build(1, 1, nr);
for (int i = 1; i <= m; i++) {
int x, y;
fin >> x >> y;
int ceva_x = pozitie[x];
int ceva_y = pozitie[y];
if (ceva_x > ceva_y) {
swap(ceva_x, ceva_y);
}
minim = 1e7;
raspuns = 0;
query(1, 1, nr, ceva_x, ceva_y);
fout << raspuns << '\n';
}
return 0;
}