Pagini recente » Cod sursa (job #3349477) | Cod sursa (job #742869) | Cod sursa (job #1936768) | Borderou de evaluare (job #2692187) | Cod sursa (job #3322975)
#include <fstream>
#include <cmath>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
vector<int> g[100001];
int i,n,q;
vector<int>euler,level,first(100001,0);
vector<int> rmq[20];
void dfs(int nod,int depth)
{
euler.push_back(nod);
level.push_back(depth);
rmq[0].push_back(rmq[0].size());
for(auto vecin:g[nod])
{
dfs(vecin,depth + 1);
level.push_back(depth);
euler.push_back(nod);
rmq[0].push_back(rmq[0].size());
}
}
int query(int l,int r)
{
int l2 = log2(r-l+1);
int rsp = rmq[l2][l];
if(level[rsp] > level[rmq[l2][r-(1<<(l2))+1]])
rsp = rmq[l2][r-(1<<(l2))+1];
return rsp;
}
int main()
{
cin>>n>>q;
level.push_back(0);
euler.push_back(0);
rmq[0].push_back(0);
first.resize(n+1,0);
for(i=1; i<=n-1; i++)
{
int elem;
cin>>elem;
g[elem].push_back(i+1);
}
dfs(1,0);
for(int p = 1; (1<<p)<=euler.size()-1; p++)
{
rmq[p].push_back(0);
for(i=1; i + (1<<p) -1 <= euler.size()-1; i++)
{
rmq[p].push_back(0);
rmq[p][i] = rmq[p-1][i];
if(level[rmq[p][i]] > level[rmq[p-1][i+(1<<(p-1))]])
rmq[p][i] = rmq[p-1][i+(1<<(p-1))];
}
}
for(int i=1; i<euler.size(); i++)
{
if(first[euler[i]] == 0)
first[euler[i]] = i;
}
for(int i=1; i<=q; i++)
{
int a,b;
cin>>a>>b;
int debug = query(min(first[a],first[b]),max(first[a],first[b]));
cout<<euler[debug]<<'\n';
}
return 0;
}