Pagini recente » Cod sursa (job #736895) | Cod sursa (job #2481696) | Cod sursa (job #1104987) | Cod sursa (job #2227163) | Cod sursa (job #2829430)
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,nr;
struct lca
{
int t,h;
vector<int> fii;
}v[100001];
int eu[200005];
int h[200005];
int a[100001];//prima aparitie a lui i;
int minim[100001][19];
void nodStDr(int k,int val)
{
int z=v[k].fii.size(),i;
nr++;
v[k].h=val;
a[k]=nr;
eu[nr]=k;
h[nr]=val;
for(i=0;i<z;i++)
{
nodStDr(v[k].fii[i],val+1);
nr++;
eu[nr]=k;
h[nr]=val;
}
}
void minime()//minim[i][j] este pozitia elementului minim in poz[]
{
int i,j,x,y;
for(i=0;i<=nr;i++)
minim[i][0]=i;
for(j=1;(1<<j)<=nr;j++)
for(i=0;i<=nr;i++)
{
x=minim[i][j-1];
y=minim[i+(1<<(j-1))][j-1];
if(eu[x]<=eu[y])
minim[i][j]=x;
else
minim[i][j]=y;
}
}
int getMinim(int st,int dr)
{
if(st>dr)
swap(st,dr);
int k,i;
k=log2(dr-st+1);
int x=minim[st][k];
int y=minim[dr-(1<<k)+1][k];
if(eu[x]<=eu[y])
return x;
return y;
}
int main()
{
int i,j,x,y,z;
f>>n>>m;
for(i=2;i<=n;i++)
{
f>>v[i].t;
v[v[i].t].fii.push_back(i);
}
nodStDr(1,0);
minime();
for(i=1;i<=m;i++)
{
f>>x>>y;
//raspunsul este nodul cu h cel mai mic din secventa [x si y] din vectorul parcurgerii euler (nod,st,dr)
//cautam intre a[x] si a[y]
g<<eu[getMinim(a[x],a[y])]<<'\n';
}
return 0;
}