Pagini recente » Cod sursa (job #3354493) | Borderou de evaluare (job #1331521) | Cod sursa (job #302222) | Borderou de evaluare (job #1336450) | Cod sursa (job #3344339)
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
struct elem
{
int nod, niv;
};
int nivel[300009];
vector <int> v[300009];
elem rmq[22][300009];
int tata[300009], lin[300009], poz[300009], ap[300009];
int cnt=0;
elem mini (elem x, elem y)
{
if (x.niv<=y.niv)
return x;
return y;
}
void dfs (int nod)
{
lin[++cnt]=nod;
if (!poz[nod]) poz[nod]=cnt;
rmq[0][cnt]={nod, nivel[nod]};
for (auto y:v[nod])
{
nivel[y]=nivel[nod]+1;
dfs (y);
lin[++cnt]=nod;
rmq[0][cnt]={nod, nivel[nod]};
}
}
int p[22];
elem query (int x, int y)
{
int st=poz[x], dr=poz[y];
if (st>dr)
swap (st, dr);
int lungime=dr-st+1;
int lg=ap[lungime];
//cout << lg << ' ';
return mini (rmq[lg][st], rmq[lg][dr-p[lg]+1]);
}
signed main ()
{
int n, m;
f >> n >> m;
for (int i=2; i<=n; i++)
{
f >> tata[i];
v[tata[i]].push_back(i);
}
dfs (1);
p[0]=1;
for (int i=1; i<=20; i++)
p[i]=2*p[i-1];
for (int i=1; p[i]<=cnt; i++)
{
//cout << i << ' ' ;
for (int j=1; j+p[i]-1<=cnt; j++)
{
rmq[i][j]=mini (rmq[i-1][j], rmq[i-1][j+p[i-1]]);
}
}
int val=1, curr=0;
for (int i=2; i<=cnt; i++)
{
while (2*val<=i)
{
curr++;
val*=2;
}
ap[i]=curr;
}
//cout<<nivel[5]<<' ';
while (m--)
{
int x, y;
f >> x >> y;
g << query (x, y).nod << '\n';
}
}