Pagini recente » Cod sursa (job #2963958) | Cod sursa (job #1936066) | Cod sursa (job #79147) | Cod sursa (job #2238256) | Cod sursa (job #2466396)
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
const int NMAX = 100005;
vector <int> graph[NMAX];
int nodes, queries;
int h[NMAX], euler[2 * NMAX], lgeuler, poseuler[2 * NMAX];
int lg[2 * NMAX], rmq[20][2 * NMAX];
void dfs(int node, int father)
{
h[node] = h[father] + 1;
euler[++lgeuler] = node;
poseuler[node] = lgeuler;
for (auto &x : graph[node])
{
dfs(x, node);
euler[++lgeuler] = node;
}
}
void BuildRMQ()
{
for (int i = 2;i <= lgeuler;++i)
lg[i] = lg[i >> 1] + 1;
for (int i = 1;i <= lgeuler;++i)
rmq[0][i] = i;
for (int p = 1;(1 << p) <= lgeuler;++p)
for (int i = 1;i + (1 << p) - 1 <= lgeuler;++i)
{
int a = rmq[p - 1][i];
int b = rmq[p - 1][i + (1 << (p - 1))];
if (h[euler[a]] < h[euler[b]])
rmq[p][i] = a;
else
rmq[p][i] = b;
}
}
int QueryRMQ(int a, int b)
{
a = poseuler[a];
b = poseuler[b];
if (a > b)
swap(a, b);
int p = lg[b - a + 1];
a = euler[rmq[p][a]];
b = euler[rmq[p][b - (1 << p) + 1]];
if (h[a] < h[b])
return a;
else
return b;
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> nodes >> queries;
for (int i = 2;i <= nodes;++i)
{
int x;
fin >> x;
graph[x].push_back(i);
}
dfs(1, 0);
BuildRMQ();
while (queries-- > 0)
{
int a, b;
fin >> a >> b;
fout << QueryRMQ(a, b) << "\n";
}
fin.close();
fout.close();
return 0;
}