Pagini recente » Cod sursa (job #63990) | Cod sursa (job #1893842) | Cod sursa (job #75023) | Cod sursa (job #2796504) | Cod sursa (job #3299034)
/**
Solutie: rmq
Complexitate: O(n log n + m)
*/
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int MAX_N = 100'000;
const int MAX_LOG = 20;
int rmq[MAX_LOG + 1][MAX_N << 2 | 1];
int pos[MAX_LOG + 1][MAX_N << 2 | 1];
int lg2[MAX_N << 1 | 1];
int euler[MAX_N << 1 | 1];
int niv[MAX_N << 1 | 1];
int first[MAX_N + 1];
int n, m, k, x, u, v;
vector<int> G[MAX_N];
void read() {
fin >> n >> m;
for (int i = 2; i <= n; i++) {
fin >> x;
G[x].push_back(i); /// x este tatal lui i
}
}
void dfs(int nod, int dist) {
euler[++k] = nod;
niv[k] = dist;
first[nod] = k;
for (int vec : G[nod]) {
dfs(vec, dist + 1);
euler[++k] = nod;
niv[k] = dist;
}
}
void init() {
lg2[1] = 0;
for (int i = 2; i <= k; i++)
lg2[i] = lg2[i >> 1] + 1;
for (int i = 1; i <= k; i++) {
rmq[0][i] = niv[i];
pos[0][i] = i;
}
for (int p = 1; p <= lg2[k]; p++)
for (int i = 1; i <= k; i++) {
if (i > k - (1 << p) + 1) {
rmq[p][i] = rmq[p - 1][i];
pos[p][i] = pos[p - 1][i];
continue;
}
if (rmq[p - 1][i] > rmq[p - 1][i + (1 << (p - 1))]) {
rmq[p][i] = rmq[p - 1][i + (1 << (p - 1))];
pos[p][i] = pos[p - 1][i + (1 << (p - 1))];
} else {
rmq[p][i] = rmq[p - 1][i];
pos[p][i] = pos[p - 1][i];
}
}
}
int lca(int u, int v) {
int posmin = 0;
int l = first[u], r = first[v];
if (l > r) {
int aux = l;
l = r;
r = aux;
}
int len = lg2[r - l + 1];
if (rmq[len][l] < rmq[len][r - (1 << len) + 1])
posmin = pos[len][l];
else
posmin = pos[len][r - (1 << len) + 1];
return euler[posmin];
}
int main() {
read();
dfs(1, 0);
auto debug = [&]() {
cout << " Euler: ";
for (int i = 1; i <= k; i++)
cout << euler[i] << " ";
cout << "\n";
cout << " Adancime: ";
for (int i = 1; i <= k; i++)
cout << niv[i] << " ";
};
debug();
init();
while (m--) {
fin >> u >> v;
fout << lca(u, v) << "\n";
}
fin.close();
fout.close();
return 0;
}