Pagini recente » Borderou de evaluare (job #451277) | Borderou de evaluare (job #1034180) | Borderou de evaluare (job #1058368) | Borderou de evaluare (job #2004907) | Cod sursa (job #932412)
Cod sursa(job #932412)
#include<cstdio>
#include<vector>
#include<utility>
#define min(a,b) ((a)<(b)?(a):(b))
#define NMAX 100005
#define LMAX 18
FILE *f=fopen("lca.in","r");
FILE *g=fopen("lca.out","w");
using namespace std;
int rmq[LMAX][NMAX<<2],first[NMAX],l[NMAX],lg[NMAX],h[NMAX];
vector <int> G[NMAX];
int k,n,m;
void read( void )
{
fscanf(f,"%d%d",&n,&m);
for(int i (2) ; i <= n; ++i)
{
int x;
fscanf(f,"%d",&x);
G[x].push_back(i);
}
}
void DFS(int node,int level)
{
h[++k]=node;
l[k]=level;
first[node]=k;
for(vector<int>::iterator it=G[node].begin() ; it!=G[node].end() ; ++it )
{
DFS(*it,level+1);
h[++k]=node;
l[k]=level;
}
}
void RMQ( void )
{
lg[1]=0;
for(int i(2) ; i<= n ; ++i )
lg[i]=lg[i/2]+1;
for(int i(1) ; i <= k ; ++i )
rmq[0][i]=i;
for(int i(1) ; (1<<i) <= k ; ++i )
for(int ii(1) ; ii <= k- (1<<i) +1 ; ++ii )
{
int len=1<<(i-1);
rmq[i][ii]=rmq[i-1][ii];
if(l[rmq[i-1][ii+len]] < l [rmq[i-1][ii]])
rmq[i][ii]=rmq[i-1][ii+len];
}
}
void lca_write( void )
{
int left;
int right;
fscanf(f,"%d%d",&left,&right);
left=first[left];
right=first[right];
if(left>right)
swap(left,right);
int diff,sx,x;
diff=right-left+1;
int la=lg[diff];
sx=diff-(1<<la);
int sol=rmq[la][left];
if(l[rmq[la][left+sx]] < l[sol])
sol=rmq[la][left+sx];
fprintf(g,"%d\n",h[sol]);
}
int main( void )
{
read();
DFS(1,0);
RMQ();
while( m--)
lca_write();
return 0;
}