Pagini recente » Cod sursa (job #232208) | Cod sursa (job #574518) | Cod sursa (job #30412) | Cod sursa (job #722331) | Cod sursa (job #2833868)
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX_N 100000
#define EULER_SIZE (MAX_N * 2 - 1)
#define LOG_EULER_SIZE 17
int logs[EULER_SIZE + 1];
vector<int> children[MAX_N + 1];
int euler[EULER_SIZE], eulerSize;
int first[MAX_N + 1];
int level[MAX_N + 1];
int table[LOG_EULER_SIZE + 1][EULER_SIZE];
void precomputeLogs(int n) {
int i;
logs[1] = 0;
for (i = 2; i <= n; ++i)
logs[i] = logs[i / 2] + 1;
}
void dfs(int node, int lvl) {
first[node] = eulerSize;
euler[eulerSize] = node;
++eulerSize;
level[node] = lvl;
for (int child : children[node]) {
dfs(child, lvl + 1);
euler[eulerSize] = node;
++eulerSize;
}
}
inline int f(int a, int b) {
return level[a] < level[b] ? a : b;
}
void computeRmq() {
int i, p;
for (i = 0; i < eulerSize; ++i)
table[0][i] = euler[i];
for (p = 1; (1 << p) <= eulerSize; ++p)
for (i = 0; i + (1 << p) - 1 < eulerSize; ++i)
table[p][i] = f(table[p - 1][i], table[p - 1][i + (1 << (p - 1))]);
}
int rmqQuery(int left, int right) {
int len, log;
len = (right - left + 1);
log = logs[len];
return f(table[log][left], table[log][right - (1 << log) + 1]);
}
int lca(int a, int b) {
a = first[a], b = first[b];
if (a > b)
swap(a, b);
return rmqQuery(a, b);
}
int main() {
FILE *fin, *fout;
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
int n, m, i, father, a, b;
fscanf(fin, "%d%d", &n, &m);
for (i = 2; i <= n; ++i) {
fscanf(fin, "%d", &father);
children[father].push_back(i);
}
dfs(1, 0);
precomputeLogs(eulerSize);
computeRmq();
while (m--) {
fscanf(fin, "%d%d", &a, &b);
fprintf(fout, "%d\n", lca(a, b));
}
fclose(fin);
fclose(fout);
return 0;
}