Pagini recente » Istoria paginii runda/simulare9_31_10_1 | Cod sursa (job #1031745) | Cod sursa (job #1612914) | Cod sursa (job #2044255) | Cod sursa (job #1546751)
#include <cstdio>
#define MAXN 100000
#define LOGN 17
#define MAXE 8000000
int ind[MAXN+1],next[2*MAXN+1],v[2*MAXN+1],cod[MAXN],dist[MAXN+1],nr=1;
int ve[MAXE+1],de[MAXE+1],rmq[2*MAXN+1][LOGN],log[MAXE],ap[MAXN+1];
char vf[MAXN+1];
inline void add(int x,int y){
next[nr]=ind[x];
ind[x]=nr;
v[nr]=y;
nr++;
}
void euler(int nod){
int poz;
ve[nr]=nod;
vf[nod]=1;
nr++;
poz=ind[nod];
while(poz){
if(vf[v[poz]]!=1){
euler(v[poz]);
ve[nr]=nod;
nr++;
}
poz=next[poz];
}
}
inline void BFS(int nod){
int b,e,poz;
cod[0]=nod;
dist[1]=1;
b=0;
e=1;
do{
poz=ind[cod[b]];
while(poz){
if(dist[v[poz]]==0){
dist[v[poz]]=dist[cod[b]]+1;
cod[e]=v[poz];
e++;
}
poz=next[poz];
}
b++;
}while(b<e);
}
inline int getmin(int a,int b){
if(a<b) return a;
return b;
}
int main(){
FILE*fi,*fout;
int n,q,i,x,p2,j,y,pmax,pmin;
fi=fopen("lca.in" ,"r");
fout=fopen("lca.out" ,"w");
fscanf(fi,"%d%d" ,&n,&q);
for(i=2;i<=n;i++){
fscanf(fi,"%d" ,&x);
add(i,x);
add(x,i);
}
BFS(1);
nr=1;
euler(1);
for(i=1;i<nr;i++){
de[i]=dist[ve[i]];
if(ap[ve[i]]==0)
ap[ve[i]]=i;
}
for(i=1;i<nr;i++)
rmq[i][0]=i;
for(i=1;(1<<i)<=nr;i++)
for(j=1;j+(1<<i)<=nr;j++)
if(de[rmq[j][i-1]]<de[rmq[j+(1<<(i-1))][i-1]])
rmq[j][i]=rmq[j][i-1];
else
rmq[j][i]=rmq[j+(1<<(i-1))][i-1];
p2=i=1;
int con=0;
while(i<=nr){
if(p2*2<=i){
p2*=2;
con++;
}
log[i]=con;
i++;
}
while(q){
q--;
fscanf(fi,"%d%d" ,&x,&y);
if(x==y)
fprintf(fout,"%d\n" ,x);
else{
if(ap[x]>ap[y]){
pmax=ap[x];
pmin=ap[y];
}
else{
pmax=ap[y];
pmin=ap[x];
}
if(de[rmq[pmin][log[pmax-pmin]]]>de[rmq[pmax-(1<<(log[pmax-pmin]))][log[pmax-pmin]]])
fprintf(fout,"%d\n" ,ve[rmq[pmax-(1<<(log[pmax-pmin]))][log[pmax-pmin]]]);
else
fprintf(fout,"%d\n" ,ve[rmq[pmin][log[pmax-pmin]]]);
}
}
fclose(fi);
fclose(fout);
return 0;
}