Pagini recente » Cod sursa (job #444518) | Cod sursa (job #2834056) | Cod sursa (job #3032949) | Cod sursa (job #2940743) | Cod sursa (job #2858545)
#include <fstream>
#include <vector>
#define NMAX 100005
#define LOG 20
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n, questions, x, y;
int first[NMAX];
int sparseTable[LOG][2 * NMAX];
vector <int> neighbours[NMAX];
vector <pair <int, int> > euler;
void DFS(int node, int level) {
euler.push_back({node, level});
if (!first[node])
first[node] = euler.size() - 1;
for (auto neighbour : neighbours[node]) {
DFS(neighbour, level + 1);
euler.push_back({node, level});
}
}
void getSparseTable() {
for (int i = 0; i < euler.size(); i++)
sparseTable[0][i] = i;
for (int i = 1; (1 << i) <= euler.size(); i++) {
for(int j = 0; j <= euler.size() - (1 << i); j++) {
int x = sparseTable[i - 1][j];
int y = sparseTable[i - 1][j + (1 << (i - 1))];
if (euler[x].second > euler[y].second)
sparseTable[i][j] = y;
else
sparseTable[i][j] = x;
}
}
}
int getRmq(int x, int y) {
int firstPoz = min(first[x], first[y]);
int lastPoz = max(first[x], first[y]);
int length = lastPoz - firstPoz + 1;
int log = 0;
while ((1 << log) <= length)
log++;
log--;
int firstVal = sparseTable[log][firstPoz];
int secondVal = sparseTable[log][lastPoz - (1 << log) + 1];
if (euler[firstVal].second < euler[secondVal].second)
return euler[firstVal].first;
return euler[secondVal].first;
}
int main()
{
f >> n >> questions;
for (int i = 2; i <= n; i++) {
f >> x;
neighbours[x].push_back(i);
}
DFS(1, 1);
getSparseTable();
while (questions--) {
f >> x >> y;
g << getRmq(x, y) << "\n";
}
return 0;
}