Pagini recente » Cod sursa (job #1219367) | Cod sursa (job #2871855) | Cod sursa (job #1443199) | Cod sursa (job #3165921) | Cod sursa (job #1833765)
#include <bits/stdc++.h>
#define NMAX 100005
#define LOG_NMAX 17
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector < int > graph[NMAX], euler;
int level[NMAX], rmq[LOG_NMAX + 1][NMAX], first[NMAX], log_2[2 * NMAX], N, M;
void readInput() {
f >> N >> M;
for (int i = 2; i <= N; ++i) {
int x;
f >> x;
graph[x].push_back(i);
}
}
void dfs(int node, int currentLevel) {
level[node] = currentLevel;
euler.push_back(node);
first[node] = euler.size();
for (auto it : graph[node]) {
dfs(it, currentLevel + 1);
euler.push_back(node);
}
}
void computeRmq() {
rmq[0][1] = euler[0];
for (int i = 2; i <= euler.size(); ++i) {
log_2[i] = log_2[i / 2] + 1;
rmq[0][i] = euler[i - 1];
}
for (int i = 1; (1 << i) <= euler.size(); ++i) {
for (int j = 1; j <= euler.size() - (1 << i) + 1; ++j) {
int x = rmq[i - 1][j];
int y = rmq[i - 1][j + (1 << (i - 1))];
/*
* Vreau nodul de nivel minim din parcurgerea Euler
*/
if (level[x] < level[y]) {
rmq[i][j] = x;
} else {
rmq[i][j] = y;
}
}
}
}
int lca(int node1, int node2) {
int left = first[node1];
int right = first[node2];
if (left > right) {
swap(left, right);
}
int lg_2 = log_2[right - left + 1];
int x = rmq[lg_2][left];
int y = rmq[lg_2][right - (1 << lg_2) + 1];
if (level[x] < level[y]) {
return x;
}
return y;
}
void computeQueries() {
for (int i = 1; i <= M; ++i) {
int node1, node2;
f >> node1 >> node2;
g << lca(node1, node2) << '\n';
}
}
int main() {
clock_t tStart = clock();
readInput();
dfs(1, 0);
computeRmq();
computeQueries();
printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
return 0;
}