Pagini recente » Cod sursa (job #2732683) | Cod sursa (job #2388251) | Cod sursa (job #1833959) | Cod sursa (job #104723) | Cod sursa (job #1975435)
#include <cstdio>
#include <vector>
#define pb push_back
using namespace std;
const int DIM=50000,nmax=100004,lmax=18;
char buff[DIM];
int poz=DIM-1;
void citeste(int &nr)
{
nr=0;
while(!('0'<=buff[poz]&&buff[poz]<='9'))
{
if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
}
while('0'<=buff[poz]&&buff[poz]<='9')
{
nr=nr*10 + buff[poz]-'0';
if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
}
}
int lvl[nmax],t[lmax][nmax];
vector<int>adj[nmax];
int n,m;
inline void citire()
{
citeste(n),citeste(m);
for(int i=1;i<n;i++)
{
citeste(t[0][i+1]);
adj[t[0][i+1]].pb(i+1);
}
}
void define_lvl(int nod)
{
for(vector<int>::iterator it=adj[nod].begin();it!=adj[nod].end();++it)
{
if(lvl[*it]==0)
{
lvl[*it]=lvl[nod]+1;
define_lvl(*it);
}
}
}
int dad(int nod,int val)
{
//printf("%d\n",(1<<1));
for(int i=17;i>=0;--i)
{
if(val&(1<<i)) nod=t[i][nod];
}
return nod;
}
int lca(int n1,int n2)
{
if(lvl[n1]>lvl[n2]) swap(n1,n2);
if(lvl[n1]!=lvl[n2]) n2=dad(n2,lvl[n2]-lvl[n1]);
//printf("%d %d\n",n1,n2);
if(n1==n2) return n1;
int rasp=n1;
for(int i=17;i>=0;--i)
{
if(t[i][n1]!=t[i][n2]&&t[i][n1]!=0&&t[i][n2]!=0)
{
rasp=t[i][n1];
n1=t[i][n1];
n2=t[i][n2];
}
}
return t[0][rasp];
}
inline void define_t()
{
for(int i=1;i<=17;i++)
{
for(int j=1;j<=n;j++) t[i][j]=t[i-1][t[i-1][j]];
}
}
inline void solve()
{
for(;m>0;--m)
{
int n1,n2;
citeste(n1),citeste(n2);
printf("%d\n",lca(n1,n2));
}
}
int main()
{
freopen ("lca.in","r",stdin);
freopen ("lca.out","w",stdout);
citire();
lvl[1]=1;
define_lvl(1);
//for(int i=1;i<=n;i++) printf("%d ",lvl[i]);
// printf("\n");
define_t();
solve();
}