Cod sursa(job #737666)

Utilizator andreipasalauPasalau Andrei andreipasalau Data 19 aprilie 2012 23:16:59
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <fstream>
#include <stdlib.h>
#include <cmath>
#define NMax 100001
#define max(a,b) a<b?b:a
#define min(a,b) a<b?a:b
using namespace std;

fstream fin("lca.in",ios::in);
fstream fout("lca.out",ios::out);

using namespace std;

int *Fii[NMax],n,m;
int euler[2*NMax][2],poz=0,lg;
int pozitie[NMax];
int *M[2*NMax];

void Citire()
{
    int tata;
    fin>>n>>m;
    for(int i=1;i<=n;i++)
        {
            Fii[i]=(int*)malloc(sizeof(int));
            Fii[i][0]=0;
        }
    for(int i=2;i<=n;i++)
    {
        fin>>tata;
        Fii[tata][0]++;
        Fii[tata]=(int*)realloc(Fii[tata],(Fii[tata][0]+1)*sizeof(int));
        Fii[tata][Fii[tata][0]]=i;
    }
}

void Euler(int nod,int nivel)
{
    euler[poz][0]=nod;
    euler[poz++][1]=nivel;
    for( int i = 1; i <= Fii[nod][0]; i++ )
    {
        Euler(Fii[nod][i],nivel+1);
        euler[poz][0]=nod;
        euler[poz++][1]=nivel;
    }
}



void Process()
{
    int i,j;
    for(int i=0;i<lg;i++)
    {
        M[i]=(int*)malloc((log2(lg-i)+1)*sizeof(int));
        M[i][0]=i;
    }
    for(j=1;1<<j<=lg;j++)
        for(i=0;i+(1<<j)-1<lg;i++)
            if(euler[M[i][j-1]][1]<euler[M[i+(1<<(j-1))][j-1]][1])
                M[i][j]=M[i][j-1];
            else    M[i][j]=M[i+(1<<(j-1))][j-1];
}

int RMQ(int i,int j)
{
    int k=(int)log2(j-i+1);
    if(euler[M[i][k]][1]<=euler[M[j-(1<<k)+1][k]][1])
        return euler[M[i][k]][0];
    else return euler[M[j-(1<<k)+1][k]][0];
}

void SolveQueries()
{
    int u,v;
    for(int i=0;i<2*n-1;i++)
    {
        pozitie[euler[i][0]]=i;
    }
    for(int i=0;i<m;i++)
    {
        fin>>u>>v;
        fout<<RMQ(min(pozitie[u],pozitie[v]),max(pozitie[u],pozitie[v]))<<"\n";
    }
}

void FreeMemory()
{
    for(int i=1;i<=n;i++)
        free(Fii[i]);
    for(int i=0;i<lg;i++)
        free(M[i]);
}


int main()
{
    Citire();
    Euler(1,0);
    lg=2*n-1;
    Process();
    SolveQueries();
    FreeMemory();
    fin.close();
    fout.close();
    return 0;
}