Pagini recente » Cod sursa (job #3334582) | Cod sursa (job #862400) | Cod sursa (job #3310648) | Diferente pentru utilizator/coco intre reviziile 2 si 3 | Cod sursa (job #3343882)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int n, m;
vector <int> g[100001];
int rmq[20][200001]; //indicele minimului in tour pe [j, j + 2 ^ i - 1]
int lg2[200001];
int tour[200001], toursize;
int h[200001];
int tin[200001], tout[200001]; //pozitia in tour in care node intra/iese
void dfs_tour(int node, int parent)
{
tour[++toursize] = node;
h[node] = h[parent] + 1;
for (auto vecin : g[node])
if (vecin != parent)
{
dfs_tour(vecin, node);
tour[++toursize] = node;
}
}
void calc_tin(int node, int parent)
{
for (int t = 1; t <= toursize; t++)
{
if (!tin[tour[t]])
tin[tour[t]] = t;
tout[tour[t]] = t;
}
}
void calc_rmq()
{
for (int j = 1; j <= toursize; j++)
rmq[0][j] = j;
lg2[1] = 0;
for (int i = 2; i <= 200000; i++)
lg2[i] = lg2[i / 2] + 1;
for (int i = 1; i <= 19; i++)
for (int j = 1; j <= (toursize - (1 << i)) + 1; j++)
if (h[tour[rmq[i - 1][j + (1 << (i - 1))]]] < h[tour[rmq[i - 1][j]]])
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
else
rmq[i][j] = rmq[i - 1][j];
}
int query(int l, int r)
{
int lung = r - l + 1;
int p = lg2[lung];
if (h[tour[rmq[p][l]]] < h[tour[rmq[p][r - (1 << p) + 1]]])
return tour[rmq[p][l]];
else
return tour[rmq[p][r - (1 << p) + 1]];
}
int main()
{
fin >> n >> m;
for (int i = 1; i <= n - 1; i++)
{
int node;
fin >> node;
g[i + 1].push_back(node);
g[node].push_back(i + 1);
}
h[0] = -1;
dfs_tour(1, 0);
calc_tin(1, 0);
calc_rmq();
for (int i = 1; i <= m; i++)
{
int x, y;
fin >> x >> y;
if (tin[x] > tin[y])
swap(x, y);
fout << query(tin[x], tin[y]) << '\n';
}
return 0;
}