Pagini recente » Cod sursa (job #2831219) | Cod sursa (job #2455329) | Cod sursa (job #3157120) | Cod sursa (job #301658) | Cod sursa (job #1918466)
#include <fstream>
#include <vector>
#include <algorithm>
#define NMax 100010
#define LogMax 17
using namespace std;
ifstream f("LCA.in");
ofstream g("LCA.out");
int nodes, euler[2 * NMax], level[2 * NMax], RMQ[LogMax][NMax], lg2[2*NMax], queries, firstOcc[NMax];
bool mark[NMax];
vector<int> G[NMax];
void DFS(int node, int lvl)
{
mark[node] = true;
++euler[0];
euler[euler[0]] = node;
level[euler[0]] = lvl;
for (auto it : G[node]) {
if (!mark[it]) {
DFS(it, lvl + 1);
++euler[0];
euler[euler[0]] = node;
level[euler[0]] = lvl;
}
}
}
void PreCompRMQ()
{
for (int i = 1; i <= euler[0]; i++) {
RMQ[0][i] = i;
if (firstOcc[euler[i]] == 0)
firstOcc[euler[i]] = i;
}
for (int i = 1; i <= lg2[euler[0]]; i++)
for (int j = 1; j <= euler[0] - (1 << i) + 1; j++)
if (level[RMQ[i - 1][j]] < level[RMQ[i - 1][j + (1 << (i - 1))]])
RMQ[i][j] = RMQ[i - 1][j];
else
RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
}
int query_range(int left, int right)
{
int span = lg2[right - left + 1];
if (level[RMQ[span][left]] < level[RMQ[span][right - (1 << span) + 1]])
return RMQ[span][left];
return RMQ[span][right - (1 << span) + 1];
}
int main()
{
f >> nodes >> queries;
for (int i = 2; i <= 2 * nodes; i++)
lg2[i] = lg2[i / 2] + 1;
int n1, n2;
for (int i = 2; i <= nodes; i++) {
f >> n1;
G[n1].push_back(i);
}
DFS(1, 0);
PreCompRMQ();
for (int i = 1; i <= queries; i++) {
f >> n1 >> n2;
int left = firstOcc[n1];
int right = firstOcc[n2];
if (left > right)
swap(left, right);
int idx = query_range(left, right);
g << euler[idx] << '\n';
}
return 0;
}