Pagini recente » Cod sursa (job #2772153) | Cod sursa (job #1540111) | Cod sursa (job #658479) | Cod sursa (job #3303447) | Cod sursa (job #3334330)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
#define in fin
#define out fout
ifstream fin("lca.in");
ofstream fout("lca.out");
const int MAXN = 1e5;
const int LOGN = 17;
struct remeq {
int nivel;
int nod;
};
int _n, n, m, tata, a, b;
remeq rmq[LOGN+5][2*MAXN+1];
int lg2[2*MAXN+1];
bool viz[2*MAXN+1];
vector<int> graf[MAXN+1];
vector<int> euler, nivele;
vector<int> aparitii(MAXN+1, -1);
void dfs_euler(int nod, int nivel) {
viz[nod] = true;
euler.push_back(nod);
nivele.push_back(nivel);
aparitii[nod] = euler.size() - 1;
for (auto e: graf[nod])
if (!viz[e]) {
dfs_euler(e, nivel + 1);
euler.push_back(nod);
nivele.push_back(nivel);
}
}
int main() {
in >> _n >> m;
for (int i = 2; i <= _n; i++) {
in >> tata;
graf[tata].push_back(i);
graf[i].push_back(tata);
}
for (auto lnd: graf)
sort(lnd.begin(), lnd.end());
dfs_euler(1, 0);
n = euler.size();
// init the rmq
for (int i = 1; i <= n; i++)
rmq[0][i] = { nivele[i-1], euler[i-1] };
// build log2 vector
lg2[0] = lg2[1] = 0;
for (int i = 2; i <= n; i++)
lg2[i] = lg2[i / 2] + 1;
// build the rmq
for (int i = 1; i <= lg2[n]; i++) {
for (int j = 1; j <= n - (1 << i) + 1; j++)
if (rmq[i-1][j].nivel < rmq[i-1][j + (1 << (i - 1))].nivel)
rmq[i][j] = rmq[i-1][j];
else
rmq[i][j] = rmq[i-1][j + (1 << (i - 1))];
}
cout << aparitii[min(14, 9)] + 1;
for (int q = 1; q <= m; q++) {
int _a, _b;
in >> _a >> _b;
a = aparitii[_a] + 1, b = aparitii[_b] + 1;
int nk = lg2[abs(b - a)];
remeq st = rmq[nk][min(a, b)];
remeq dr = rmq[nk][max(a, b) - (1 << nk) + 1];
if (st.nivel <= dr.nivel)
out << st.nod << '\n';
else
out << dr.nod << '\n';
}
return 0;
}