Pagini recente » Cod sursa (job #1983045) | Cod sursa (job #707059) | Cod sursa (job #275416) | Cod sursa (job #495949) | Cod sursa (job #2961064)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
struct elem
{
int val, etaj;
};
int n, q, rmq[20][400005], prima_ap[400005], x, y;
bool vizitat[100005];
vector<int> G[100005];
vector<elem> euler;
void buildRMQ()
{
for (int i = 0; i < euler.size(); i++)
rmq[0][i] = i;
int logar = log2(n);
for (int i = 1; i <= logar; i++)
{
int put = 1 << i;
for (int j = 0; j + put < euler.size(); j++)
{
int st = rmq[i - 1][j];
int dr = rmq[i - 1][j + (1 << (i - 1))];
if (euler[st].etaj > euler[dr].etaj)
rmq[i][j] = dr;
else
rmq[i][j] = st;
}
}
}
int query(int x, int y)
{
if (prima_ap[x] > prima_ap[y])
swap(x, y);
int logar = log2(prima_ap[y] - prima_ap[x] + 1), sol;
int st = rmq[logar][prima_ap[x]];
int dr = rmq[logar][prima_ap[x] + (prima_ap[y] - prima_ap[x] + 1) - (1 << logar)];
if (euler[st].etaj > euler[dr].etaj)
sol = dr;
else
sol = st;
return euler[sol].val;
}
void DFS(int nod, int etaj)
{
vizitat[nod] = true;
prima_ap[nod] = euler.size();
euler.push_back({nod, etaj});
for (int i = 0; i < G[nod].size(); i++)
{
int vecin = G[nod][i];
if (vizitat[vecin] == false)
DFS(vecin, etaj + 1);
euler.push_back({nod, etaj});
}
}
int main()
{
fin >> n >> q;
for (int i = 2; i <= n; i++)
{
int x;
fin >> x;
G[x].push_back(i);
}
DFS(1, 0);
buildRMQ();
for (int i = 0; i < q; i++)
{
fin >> x >> y;
fout << query(x, y) << "\n";
}
return 0;
}