Pagini recente » Cod sursa (job #1646287) | Cod sursa (job #3290122) | Cod sursa (job #2938972) | Cod sursa (job #624962) | Cod sursa (job #2085934)
#include <fstream>
#include <vector>
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
const int nmax=1e5+5,INF=(1<<30);
int n,m,a,b,x,nivel[nmax],lvl_euler[3*nmax],euler[3*nmax],first[nmax],ctr,dp[3*nmax][20];
vector <int> v[nmax];
void explore(int x)
{
euler[++ctr]=x;
if(first[x]==0)
first[x]=ctr;
for(auto y:v[x])
{
explore(y);
euler[++ctr]=x;
}
}
int sol(int x,int y)
{
if(x>y)
swap(x,y);
int d=y-x+1;
int k=0;
while((1<<(k+1))<=d)
k++;
return min(dp[x][k],dp[y-(1<<k)+1][k]);
}
int main()
{
fi>>n>>m;
nivel[1]=0;
for(int i=2;i<=n;i++)
{
fi>>x;
nivel[i]=nivel[x]+1;
v[x].push_back(i);
}
explore(1);
for(int i=1;i<=ctr;i++)
lvl_euler[i]=nivel[euler[i]];
for(int j=1;(1<<j)<=ctr;j++)
for(int i=1;i<=ctr;i++)
dp[i][j]=INF;
for(int i=1;i<=ctr;i++)
dp[i][0]=euler[i];
for(int j=1;(1<<j)<=ctr;j++)
for(int i=1;i<=ctr;i++)
if(nivel[dp[i][j-1]]<nivel[dp[i+(1<<(j-1))][j-1]])
dp[i][j]=dp[i][j-1];
else
dp[i][j]=dp[i+(1<<(j-1))][j-1];
for(int i=1;i<=m;i++)
{
fi>>a>>b;
fo<<sol(first[a],first[b])<<"\n";
}
fi.close();
fo.close();
return 0;
}