Pagini recente » Cod sursa (job #432087) | Cod sursa (job #1324831) | Cod sursa (job #1207833) | Cod sursa (job #738305) | Cod sursa (job #1367375)
#include<stdio.h>
#include<vector>
using namespace std;
int euler[205000],nivel[205000],p=1;
int pos[105000];
int lg[105000];
int d[105000][30];
vector<int> *l;
void parc(int po,int niv)
{
int t;
if(pos[po]==0)
{
pos[po]=p;
}
euler[p]=po;
nivel[p]=niv;
p++;
while(!l[po].empty())
{
t=l[po].back();
l[po].pop_back();
parc(t,niv+1);
euler[p]=po;
nivel[p]=niv;
p++;
}
}
int main()
{
FILE *fin,*fout;
fin=fopen("lca.in","r");
fout=fopen("lca.out","w");
int n,m,t;
fscanf(fin,"%d %d",&n,&m);
l=new vector<int>[n+1];
for(int i=2;i<=n;i++)
{
fscanf(fin,"%d",&t);
l[t].push_back(i);
}
parc(1,0);
/*for(int i=1;i<p;i++)
{
fprintf(fout,"%d ",euler[i]);
}
fprintf(fout,"\n");
for(int i=1;i<p;i++)
{
fprintf(fout,"%d ",nivel[i]);
}
fprintf(fout,"\n");
for(int i=1;i<=n;i++)
{
fprintf(fout,"%d ",pos[i]);
}*/
int temp,temp2;
lg[0]=0;
lg[1]=0;
for(int i=2;i<=n;i++)
{
t=i;
while(t%2==0)
{
t/=2;
}
if(t==1)
{
lg[i]=lg[i-1]+1;
}
else
{
lg[i]=lg[i-1];
}
}
//fprintf(fout,"\n");
for(int i=1;i<p;i++)
{
d[i][0]=i;
}
//fprintf(fout,"\n");
for(int j=1;j<17;j++)
{
for(int i=1;i<p;i++)
{
if(nivel[d[i][j-1]]<=nivel[d[i+(1<<(j-1))][j-1]]&&i+(1<<(j-1))<p)
{
d[i][j]=d[i][j-1];
}
else if(i+(1<<(j-1))<p)
{
d[i][j]=d[i+(1<<(j-1))][j-1];
}
}
}
/*for(int i=1;i<p;i++)
{
for(int j=0;j<17;j++)
{
fprintf(fout,"%d ",d[i][j]);
}
fprintf(fout,"\n");
}*/
for(int i=0;i<m;i++)
{
fscanf(fin,"%d %d",&temp,&temp2);
if(pos[temp]<pos[temp2])
{
if(nivel[d[pos[temp]][lg[pos[temp2]-pos[temp]+1]]]<nivel[d[pos[temp2]-(1<<(lg[pos[temp2]-pos[temp]+1]))+1][lg[pos[temp2]-pos[temp]+1]]])
{
fprintf(fout,"%d\n",euler[d[pos[temp]][lg[pos[temp2]-pos[temp]+1]]]);
}
else
{
fprintf(fout,"%d\n",euler[d[pos[temp2]-(1<<(lg[pos[temp2]-pos[temp]+1]))+1][lg[pos[temp2]-pos[temp]+1]]]);
}
}
else
{
if(nivel[d[pos[temp2]][lg[pos[temp]-pos[temp2]+1]]]<nivel[d[pos[temp]-(1<<(lg[pos[temp]-pos[temp2]+1]))+1][lg[pos[temp]-pos[temp2]+1]]])
{
fprintf(fout,"%d\n",euler[d[pos[temp2]][lg[pos[temp]-pos[temp2]+1]]]);
}
else
{
fprintf(fout,"%d\n",euler[d[pos[temp]-(1<<(lg[pos[temp]-pos[temp2]+1]))+1][lg[pos[temp]-pos[temp2]+1]]]);
}
}
}
}