Pagini recente » Cod sursa (job #3315196) | Cod sursa (job #1997070) | Cod sursa (job #529952) | Cod sursa (job #546677) | Cod sursa (job #3330316)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 1e5 + 1;
const int KMAX = 20;
vector<int> g[NMAX];
vector<pair<int, int>> eul;
vector<int> f, lvl;
int rmq[KMAX][2 * NMAX];
int lg[2 * NMAX];
void DFS(int x)
{
f[x] = eul.size();
eul.push_back({lvl[x], x});
for (auto &y : g[x])
{
lvl[y] = lvl[x] + 1;
DFS(y);
eul.push_back({lvl[x], x});
}
}
int getNodeWithMinDepth(int a, int b)
{
if (eul[a] < eul[b])
return a;
return b;
}
void computeRMQ()
{
for (int i = 2; i < eul.size(); ++i)
lg[i] = lg[i / 2] + 1;
for (int i = 1; i < eul.size(); ++i)
rmq[0][i] = i;
for (int i = 1; (1 << i) < eul.size(); ++i)
for (int j = 1; j + (1 << i) - 1 < eul.size(); ++j)
rmq[i][j] = getNodeWithMinDepth(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
}
int query(int left, int right)
{
left = f[left];
right = f[right];
if (left > right)
swap(left, right);
int i = lg[right - left + 1];
return eul[getNodeWithMinDepth(rmq[i][left], rmq[i][right - (1 << i) + 1])].second;
}
int main()
{
int n, q;
fin >> n >> q;
f.resize(n + 1);
lvl.resize(n + 1);
int t;
for (int i = 2; i <= n; ++i)
{
fin >> t;
g[t].push_back(i);
}
lvl[1] = 0;
eul.push_back({0, 0});
DFS(1);
computeRMQ();
int x, y;
while (q--)
{
fin >> x >> y;
fout << query(x, y) << '\n';
}
return 0;
}