Pagini recente » Cod sursa (job #1268754) | Cod sursa (job #3170421) | Cod sursa (job #2608693) | Cod sursa (job #632185) | Cod sursa (job #2833859)
#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[EULER_SIZE][LOG_EULER_SIZE + 1];
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;
}
}
void computeRmq() {
int i, p;
for (i = 0; i < eulerSize; ++i)
table[i][0] = euler[i];
for (p = 1; (1 << p) <= eulerSize; ++p)
for (i = 0; i + (1 << p) - 1 < eulerSize; ++i) {
table[i][p] = table[i][p - 1];
if (level[table[i][p]] > level[table[i + (1 << (p - 1))][p - 1]])
table[i][p] = table[i + (1 << (p - 1))][p - 1];
}
}
int rmqQuery(int left, int right) {
int len, log, result;
len = (right - left + 1);
log = logs[len];
result = table[left][log];
if (level[result] > level[table[right - (1 << log) + 1][log]])
result = table[right - (1 << log) + 1][log];
return result;
}
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;
}