Pagini recente » Cod sursa (job #2585809) | Cod sursa (job #44630) | Cod sursa (job #2687027) | Cod sursa (job #2557924) | Cod sursa (job #2622568)
#include <cstdio>
#include <vector>
#define MAX_NODES 100009
#define MAX_EDGES 2000009
#define LOG_N 20
std::vector<int> g_euler_tour;
std::vector<int> g_first_occurence(MAX_NODES);
std::vector<int> g_node_level(MAX_NODES);
std::vector<int> g_graph[MAX_NODES];
int number_of_nodes;
int number_of_requests;
int g_precomputed_minimum[2 * MAX_NODES][LOG_N];
int g_log[2 * MAX_NODES];
void dfs(int p_root, int p_level)
{
g_first_occurence[p_root] = g_euler_tour.size();
g_euler_tour.push_back(p_root);
g_node_level[p_root] = p_level;
for (auto& i : g_graph[p_root])
{
dfs(i, p_level + 1);
g_euler_tour.push_back(p_root);
}
}
int get_node_with_minimum_high(int i, int j)
{
return (g_node_level[i] < g_node_level[j]) ? i : j;
}
void precompute()
{
for (int i = 0; i < g_euler_tour.size(); ++i)
{
g_precomputed_minimum[i][0] = g_euler_tour[i];
}
for (int j = 1; j <= LOG_N; ++j)
{
for (int i = 0; i + (1 << j) <= g_euler_tour.size(); ++i)
{
g_precomputed_minimum[i][j] = get_node_with_minimum_high(g_precomputed_minimum[i][j - 1], g_precomputed_minimum[i + (1 << (j - 1))][j - 1]);
}
}
}
int get_lca(int l, int r)
{
int first = g_first_occurence[l];
int second = g_first_occurence[r];
if (first > second)
std::swap(first, second);
int l_interval_legth = g_log[second - first + 1];
return get_node_with_minimum_high(g_precomputed_minimum[first][l_interval_legth],
g_precomputed_minimum[second - (1 << l_interval_legth) + 1][l_interval_legth]);
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &number_of_nodes, &number_of_requests);
int l_temp_var{};
for (int i = 0; i < number_of_nodes - 1; ++i)
{
scanf("%d", &l_temp_var);
g_graph[l_temp_var].push_back(i + 2);
}
dfs(1, 0);
for (int i = 2; i < g_euler_tour.size(); ++i)
g_log[i] = g_log[i >> 1] + 1;
precompute();
int x{}, y{};
while (number_of_requests--)
{
scanf("%d%d", &x, &y);
printf("%d\n", get_lca(x, y));
}
return 0;
}