Pagini recente » Cod sursa (job #763893) | Cod sursa (job #166904) | Cod sursa (job #1098488) | Cod sursa (job #2946953) | Cod sursa (job #3330211)
#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<int> eul;
vector<int> ap;
int rmq[KMAX][2 * NMAX];
int lg[2 * NMAX];
void DFS(int x)
{
ap[x] = eul.size();
eul.push_back(x);
for (auto &y : g[x])
{
DFS(y);
eul.push_back(x);
}
}
int getNodeWithMinDepth(int a, int b)
{
if (ap[a] < ap[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] = eul[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 = ap[left];
right = ap[right];
if (left > right)
swap(left, right);
int i = lg[right - left + 1];
return getNodeWithMinDepth(rmq[i][left], rmq[i][right - (1 << i) + 1]);
}
int main()
{
int n, q;
fin >> n >> q;
ap.resize(n + 1);
int t;
for (int i = 2; i <= n; ++i)
{
fin >> t;
g[t].push_back(i);
}
eul.push_back(0);
DFS(1);
computeRMQ();
int x, y;
while (q--)
{
fin >> x >> y;
fout << query(x, y) << '\n';
}
return 0;
}