Pagini recente » Cod sursa (job #2585009) | Cod sursa (job #1518689) | Cod sursa (job #2681613) | Cod sursa (job #2272395) | Cod sursa (job #3178486)
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
ifstream fin("lca2.in");
ofstream fout("lca.out");
const int NMAX = 100001;
const int LMAX = 17;
vector<vector<int>> arbore;
vector<int> niveluri, turEuler, primaAparitie, lg(NMAX);
int rmq[LMAX][2 * NMAX], n, m;
void dfs(int nodCurent, int nivelCurent) {
primaAparitie[nodCurent] = turEuler.size();
turEuler.push_back(nodCurent);
niveluri.push_back(nivelCurent);
for (int copil : arbore[nodCurent]) {
dfs(copil, nivelCurent + 1);
turEuler.push_back(nodCurent);
niveluri.push_back(nivelCurent);
}
}
void d_rmq(int i) {
for (int j = 0; j <= turEuler.size() - 1; j++)
cout << setw(2) << rmq[i][j] << ' ';
cout << endl;
}
void calculeazaRMQ() {
for (int i = 0; i < turEuler.size(); i++)
rmq[0][i] = i;
for (int i = 1; (1 << i) <= turEuler.size(); i++) {
for (int j = 0; j + (1 << i) <= turEuler.size(); j++) {
int opt1 = rmq[i - 1][j];
int opt2 = rmq[i - 1][j + (1 << (i - 1))];
rmq[i][j] = (niveluri[opt1] < niveluri[opt2]) ? opt1 : opt2;
}
// cout << "rmq " << i << " \n";
// d_rmq(i);
}
}
int lca(int u, int v) {
int start = primaAparitie[u], end = primaAparitie[v];
if (start > end)
swap(start, end);
int lungime = end - start + 1;
int k = lg[lungime];
int opt1 = rmq[k][start];
int opt2 = rmq[k][end - (1 << k) + 1];
if (niveluri[opt1] < niveluri[opt2])
return turEuler[opt1];
else
return turEuler[opt2];
}
int main() {
fin >> n >> m;
arbore.resize(n + 1);
primaAparitie.resize(n + 1);
for (int nod = 2, parinte; nod <= n; nod++) {
fin >> parinte;
arbore[parinte].push_back(nod);
}
dfs(1, 0);
#pragma region d
// for (int i = 0; i < turEuler.size(); i++)
// cout << setw(2) << i << ' ';
// cout << '\n';
// for (int nod : turEuler)
// cout << setw(2) << nod << ' ';
// cout << '\n';
// for (int nivel : niveluri)
// cout << setw(2) << nivel << ' ';
// cout << '\n';
// for (int loc : primaAparitie)
// cout << setw(2) << loc << ' ';
// cout << '\n';
#pragma endregion d
lg[1] = 0;
for (int i = 2; i <= turEuler.size(); i++)
lg[i] = lg[i / 2] + 1;
// calculeazaRMQ();
for (int i = 0, u, v; i < m; i++) {
fin >> u >> v;
fout << lca(u, v) << '\n';
}
return 0;
}