Pagini recente » Cod sursa (job #2179006) | Cod sursa (job #2215277) | Cod sursa (job #1942927) | Cod sursa (job #3125183) | Cod sursa (job #3314774)
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int nmax=1e6+5;
const int inf=2e6+5;
int n,q,euler[2*nmax],k,ind[nmax],h[2*nmax];
int aint[3*nmax+5],m;
vector <int> gr[nmax],v;
bool viz[nmax];
void eulertour(int u, int level, int parent)
{
viz[u]=1;
euler[k]=u;
h[k]=level;
if ( ind[u]==-1 ) ind[u]=k;
k++;
for (auto nod:gr[u] )
{
if ( !viz[nod] )
{
eulertour(nod,level+1,u);
euler[k]=u;
h[k]=level;
k++;
}
}
}
void nxt2(int &n)
{
while ( n&(n-1) ) n+=(n&-n);
}
void build()
{
for (int i=0; i<m; i++ )
aint[i+m]=i;
for (int i=m-1; i>=1; i-- )
{
int l=aint[2*i]; int r=aint[2*i+1];
if ( h[l]<h[r] ) aint[i]=l;
else aint[i]=r;
}
}
int query(int l, int r)
{
l+=m; r+=m;
int index=-1;
while ( l<=r )
{
if ( l&1 )
{
if ( index==-1 || h[aint[l]]<h[index] )
index=aint[l];
l++;
}
l>>=1;
if ( !(r&1) )
{
if ( index==-1 || h[aint[r]]<h[index] )
index=aint[r];
r--;
}
r>>=1;
}
return index;
}
int lca(int x, int y)
{
x=ind[x];
y=ind[y];
if ( x>y ) swap(x,y);
return euler[query(x,y)];
}
int main()
{
f >> n >> q;
for (int i=2; i<=n; i++ )
{
int x; f >> x;
gr[x].push_back(i);
gr[i].push_back(x);
}
for (int i=1; i<=n; i++ ) ind[i]=-1;
eulertour(1,0,0);
m=k;
nxt2(m);
build();
while ( q-- )
{
int x,y;
f >> x >> y;
g << lca(x,y) << '\n';
}
return 0;
}