Pagini recente » Cod sursa (job #2400818) | Cod sursa (job #50980) | Cod sursa (job #1855375) | Cod sursa (job #867530) | Cod sursa (job #3131214)
#include <fstream>
#include <vector>
using namespace std;
const int N = 1e5;
const int L = 16;
int n_e, eul[2*N], nivel[N+1], prima_ap[N+1];
int n, r[L+1][N+1], log2[N+1];
vector <int> fii[N+1];
void dfs_euler(int x)
{
eul[++n_e] = x;
prima_ap[x] = n_e;
for (auto y: fii[x])
{
nivel[y] = 1 + nivel[x];
dfs_euler(y);
eul[++n_e] = x;
}
}
void constructie_rmq()
{
int n_r = 2*n - 1;
for (int j = 1; j <= n_r; j++)
{
r[0][j] = eul[j];
}
for (int i = 1; (1 << i) <= n_r; i++)
{
for (int j = (1 << i); j <= n_r; j++)
{
int p2 = (1 << (i - 1));
int rez_st = r[i-1][j-p2];
int rez_dr = r[i-1][j];
if (nivel[rez_st] <= nivel[rez_dr])
{
r[i][j] = rez_st;
}
else
{
r[i][j] = rez_dr;
}
}
}
log2[1] = 0;
for (int i = 2; i <= n_r; i++)
{
log2[i] = 1 + log2[i/2];
}
}
int interogare_rmq(int st, int dr)
{
int e = log2[dr-st+1];
int p2 = (1 << e);
int rez_st = r[e][st+p2-1];
int rez_dr = r[e][dr];
if (nivel[rez_st] <= nivel[rez_dr])
{
return rez_st;
}
return rez_dr;
}
int lca(int x, int y)
{
int st = prima_ap[x];
int dr = prima_ap[y];
if (st > dr)
{
swap(st, dr);
}
return interogare_rmq(st, dr);
}
int main()
{
ifstream in("lca.in");
ofstream out("lca.out");
int q;
in >> n >> q;
for (int i = 2; i <= n; i++)
{
int t;
in >> t;
fii[t].push_back(i);
}
dfs_euler(1);
constructie_rmq();
for (int i = 0; i < q; i++)
{
int x, y;
in >> x >> y;
out << lca(x, y) << "\n";
}
in.close();
out.close();
return 0;
}