Pagini recente » Cod sursa (job #3348833) | Cod sursa (job #3348835) | Borderou de evaluare (job #2355308) | Borderou de evaluare (job #2576511) | Cod sursa (job #3353907)
#include <fstream>
#include <vector>
std::ifstream fin("lca.in");
std::ofstream fout("lca.out");
using namespace std;
const int MAXLOG = 16;
vector<vector<int>> RMQ;
vector<int> Height;
int N,Q;
void read()
{
fin >> N >> Q;
RMQ.resize(MAXLOG+1,vector<int>(N+1,0));
Height.resize(N+1,0);
RMQ[0][1] = 1;
for(int i = 2; i <= N; ++i)
fin >> RMQ[0][i];
}
int getH(int nod)
{
if(RMQ[0][nod] == nod)
return Height[nod] = 1;
if(Height[nod] == 0)
return (Height[nod] = getH(RMQ[0][nod]) + 1);
return Height[nod];
}
void build_RMQ()
{
for(int i = 1; i <= N; ++i)
getH(i);
for(int len = 1; len <= MAXLOG; ++len)
for(int i = 1; i <= N; ++i)
RMQ[len][i] = RMQ[len-1][RMQ[len-1][i]];
}
int LCA(int u,int v)
{
if(Height[u] < Height[v])
swap(u,v);
for(int len = MAXLOG; len >= 0; --len)
if(Height[u] - (1 << len) >= Height[v])
u = RMQ[len][u];
if(u == v)
return u;
for(int len = MAXLOG; len >= 0; --len)
if(RMQ[len][u] && RMQ[len][u] != RMQ[len][v])
{
u = RMQ[len][u];
v = RMQ[len][v];
}
return RMQ[0][u];
}
int main()
{
ios::sync_with_stdio(false);
fin.tie(0);
read();
build_RMQ();
int x,y;
while(Q--)
{
fin >> x >> y;
fout << LCA(x,y) << '\n';
}
}