Pagini recente » Cod sursa (job #2335653) | Borderou de evaluare (job #2139335) | Cod sursa (job #2707653) | Borderou de evaluare (job #802483) | Cod sursa (job #2974653)
#include <bits/stdc++.h>
using namespace std;
int poz=0,n;
int st[100005];
int dr[100005];
vector<int>fiu[100005];
pair<int,int> rmq[20][200005];
ifstream in("lca.in");
ofstream out("lca.out");
void build()
{
n*=2;
for(int i=1; i<=log2(n); i++)
{
for(int j=1; j<=n-(1<<i)+1; j++)
{
pair<int,int>a=rmq[i-1][j];
pair<int,int>b=rmq[i-1][j+(1<<(i-1))];
if(a.second<=b.second)
rmq[i][j]=a;
else
rmq[i][j]=b;
}
}
}
int query(int a, int b)
{
if(st[a]<=st[b] && dr[b]<=dr[a])
return rmq[0][st[a]].first;
if(st[b]<=st[a] && dr[a]<=dr[b])
return rmq[0][st[b]].first;
if(dr[a]<=st[b])
a=dr[a],b=st[b];
else
a=st[a],b=dr[b],swap(a,b);
int dist=log2(b-a);
pair<int,int>x=rmq[dist][a];
pair<int,int>y=rmq[dist][b-(1<<dist)+1];
if(x.second<=y.second)
return x.first;
return y.first;
}
void euler(int nod, int grad)
{
rmq[0][++poz].first=nod;
rmq[0][poz].second=grad;
st[nod]=poz;
for(int i=0; i<fiu[nod].size(); i++)
{
euler(fiu[nod][i],grad+1);
rmq[0][++poz].first=nod;
rmq[0][poz].second=grad;
}
dr[nod]=poz;
return;
}
int main()
{
int m,a,b;
in>>n>>m;
for(int i=2; i<=n; i++)
{
in>>a;
fiu[a].push_back(i);
}
euler(1,0);
build();
for(int i=0;i<m;i++)
{
in>>a>>b;
out<<query(a,b)<<'\n';
}
}