Pagini recente » Cod sursa (job #493034) | Cod sursa (job #1166145) | Cod sursa (job #1269659) | Cod sursa (job #817679) | Cod sursa (job #2355383)
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <unordered_map>
using namespace std;
struct euler {
int v;
euler *ts;
euler() {
v = 0;
ts = nullptr;
}
};
struct ends {
euler *first;
euler *last;
ends() {
first = nullptr;
last = nullptr;
}
};
int main() {
euler e1, *aux;
if (freopen("lca.in", "r", stdin) == nullptr) {
return 1;
}
freopen("lca.out", "w", stdout);
int n, m, k = 1;
int *p = new int[200001]();
scanf("%d %d\n", &n, &m);
euler* e = new euler[2 * n + 1]();
ends* inst = new ends[n + 1]();
//citesc vector parinti
for (int i = 1; i < n; i++)
scanf("%d", &p[i + 1]);
//parcurgere euler
for (int i = 2; i <= n; i++) {
//daca nu exista nodul parinte in parcurgere
if (inst[p[i]].first == nullptr) {
//adaug nodul parinte la sfarsitul vectorului parcurgere si salvez prima si ultima aparitie a nodului
e[k].v = p[i];
inst[e[k].v].first = &e[k];
inst[e[k].v].last = &e[k];
k++;
}
//daca nu exista nodul subordonat in parcurgere
if (inst[i].first == nullptr) {
//adaug nodul subordonat la sfarsitul vectorului parcurgere si salvez prima si ultima aparitie a nodului
e[k].v = i;
inst[e[k].v].first = &e[k];
inst[e[k].v].last = &e[k];
k++;
}
aux = (*(inst[p[i]].last)).ts;
(*(inst[p[i]].last)).ts = inst[i].first;
e[k].v = p[i];
e[k].ts = aux;
inst[e[k].v].last = &e[k];
k++;
(*(inst[i].last)).ts = inst[p[i]].last;
}
e1 = *inst[1].first;
p[1] = 0;
for (int i = 2; i <= 2 * n + 1; i++) {
p[i] = p[i / 2] + 1;
}
delete[] inst;
int** a = new int*[p[2 * n + 1]];
a[0] = new int[2 * n + 1];
int c = 0;
unordered_map<int, int> *map = new unordered_map<int, int>;
while (e1.ts != nullptr) {
e1 = *e1.ts;
a[0][c] = e1.v;
if (map->find(e1.v) == map->end()) {
map->insert(make_pair(e1.v, c));
}
// printf("%d ", e1.v);
c++;
}
delete[] e;
int r = 1;
for (int i = 1; i < p[c]; i++) {
r *= 2;
a[i] = new int[c - r + 1];
for (int j = 0; j < c - r + 1; j++) {
a[i][j] = min(a[i - 1][j], a[i - 1][j + r / 2]);
}
}
int n1, n2;
for (int i = 0; i < m; i++) {
scanf("%d %d", &n1, &n2);
n1 = map->at(n1);
n2 = map->at(n2);
if (n1 > n2) {
swap(n2, n1);
}
r = 1 << p[n2 - n1 + 1];
printf("%d\n", min(a[p[n2 - n1 + 1]][n1], a[p[n2 - n1 + 1]][n2 - r + 1]));
}
delete[] p;
for (int i = 0; i < p[c]; i++) {
delete[] a[i];
}
delete[] a;
delete map;
return 0;
}