Cod sursa(job #932425)

Utilizator superman_01Avramescu Cristian superman_01 Data 28 martie 2013 21:43:01
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include<cstdio>
#include<vector>
#include<utility>

#define min(a,b) ((a)<(b)?(a):(b))
#define NMAX 100005
#define LMAX 20

FILE *f=fopen("lca.in","r");
FILE *g=fopen("lca.out","w");

using namespace std;

int rmq[LMAX][NMAX<<2],first[NMAX],l[NMAX<<1],lg[NMAX<<1],h[NMAX<<1];
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;
}