Pagini recente » Cod sursa (job #2365033) | Cod sursa (job #648939) | Cod sursa (job #2795333) | Cod sursa (job #2059902) | Cod sursa (job #632975)
Cod sursa(job #632975)
#include <fstream>
#include <cstdio>
#include <iostream>
#include <vector>
#define MAXN 100001
#define MAXRMQ 20
#define min(a, b) (a) < (b) ? a : b
#define max(a, b) (a) > (b) ? a : b
using namespace std;
vector<int> tree[MAXN];
int first_appearance_index[MAXN];
int euler_level[MAXN << 2];
int euler_node[MAXN << 2];
int rmq[MAXRMQ][MAXN << 2];
int log[MAXN << 2];
int euler_size;
void calculate_euler(int node, int level) {
first_appearance_index[node] = euler_size++;
euler_level[euler_size - 1] = level;
euler_node[euler_size - 1] = node;
for(unsigned int i = 0; i < tree[node].size(); i++) {
calculate_euler(tree[node][i], level + 1);
euler_size++;
euler_level[euler_size - 1] = level;
euler_node[euler_size - 1] = node;
}
}
void precalculate_rmq() {
for(unsigned int i = 2; i < euler_size; i++)
log[i] = log[i >> 1] + 1;
for(unsigned int j = 0; j < euler_size; j++)
rmq[0][j] = j;
int offset;
for(unsigned int i = 1; (1 << i) <= euler_size; i++)
for(unsigned int j = 0; j <= euler_size - (1 << i); j++) {
offset = 1 << (i - 1);
rmq[i][j] = rmq[i - 1][j + offset];
if (euler_level[rmq[i - 1][j]] < euler_level[rmq[i][j]])
rmq[i][j] = rmq[i - 1][j];
}
}
int get_rmq_min(int index1, int index2) {
int distance = index2 - index1 + 1;
int lg = log[distance];
int offset = distance - (1 << lg);
return euler_level[rmq[lg][index1]] < euler_level[rmq[lg][index1 + offset]] ? rmq[lg][index1] : rmq[lg][index1 + offset];
}
int main(void) {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int nodes, queries;
scanf("%d%d", &nodes, &queries);
int father;
for (int i = 1; i < nodes; i++) {
scanf("%d", &father);
tree[father].push_back(i + 1);
}
calculate_euler(1, 0);
precalculate_rmq();
int node1, node2;
int index1, index2;
while(queries--) {
scanf("%d%d", &node1, &node2);
index1 = first_appearance_index[node1];
index2 = first_appearance_index[node2];
if (index1 < index2)
printf("%d\n", euler_node[get_rmq_min(index1, index2)]);
else
printf("%d\n", euler_node[get_rmq_min(index2, index1)]);
}
return 0;
}