Pagini recente » Cod sursa (job #2254912) | Cod sursa (job #2853927) | Cod sursa (job #2279273) | Cod sursa (job #75054) | Cod sursa (job #3299039)
/**
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 = 19;
int rmq[MAX_LOG + 1][(MAX_N << 1) | 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 + 1];
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;
}
}
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 (niv[rmq[len][l]] < niv[rmq[len][r - (1 << len) + 1]])
posmin = rmq[len][l];
else
posmin = rmq[len][r - (1 << len) + 1];
return euler[posmin];
}
int main() {
read();
dfs(1, 0);
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] = 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];
continue;
}
if (niv[rmq[p - 1][i]] > niv[rmq[p - 1][i + (1 << (p - 1))]])
rmq[p][i] = rmq[p - 1][i + (1 << (p - 1))];
else
rmq[p][i] = rmq[p - 1][i];
}
while (m--) {
fin >> u >> v;
fout << lca(u, v) << "\n";
}
fin.close();
fout.close();
return 0;
}