Pagini recente » Cod sursa (job #2662711) | Cod sursa (job #2577700) | Cod sursa (job #2530133) | Cod sursa (job #2305546) | Cod sursa (job #3273204)
#include <fstream>
#include <vector>
#define FAST ios_base::sync_with_stdio(false);
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int N=1e5;
int n,q,i,j;
vector<int> g[N+2],first(N);
vector<pair<int,int>> euler;
int rmq[2*N+2][20],log2[2*N+2];
void eulertour(int u,int marked,int depth)
{
first[u]=euler.size();
euler.push_back({u,depth});
for(auto v:g[u])
{
if(v==marked)
continue;
eulertour(v,u,depth+1);
euler.push_back({u,depth});
}
}
void rmq_()
{
for(i=0; i<euler.size(); i++)
rmq[i][0]=i;
for(i=1; (1<<i)<=euler.size(); i++)
for(j=0; j+(1<<i)-1<euler.size(); j++)
{
int stabove=rmq[j][i-1];
int drabove=rmq[j+(1<<(i-1))][i-1];
if(euler[stabove].second<euler[drabove].second)
rmq[j][i]=stabove;
else
rmq[j][i]=drabove;
}
}
int lca(int x,int y)
{
x=first[x];
y=first[y];
if(x>y) swap(x,y);
int lvl=log2[y-x+1];
int firstcut=rmq[x][lvl];
int secondcut=rmq[y-(1<<lvl)+1][lvl];
if(euler[firstcut].second<euler[secondcut].second)
return euler[firstcut].first;
return euler[secondcut].first;
}
int main()
{
FAST
cin>>n>>q;
for(i=2; i<=n; i++)
{
int x;
cin>>x;
g[x].push_back(i);
g[i].push_back(x);
}
eulertour(1,0,0);
rmq_();
for(i=2; i<=2*N; i++)
log2[i]=log2[i/2]+1;
while(q--)
{
int u,v;
cin>>u>>v;
cout<<lca(u,v)<<'\n';
}
return 0;
}