Cod sursa(job #2507457)

Utilizator daniel.vbVasile Daniel daniel.vb Data 10 decembrie 2019 12:07:52
Problema Lowest Common Ancestor Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <stdio.h>

#define N 100001
#define M 20

int n,m,tata[N],lev[N],prim[N],urm[N],x[2*N],poz[N],a[2*N][M],lg2[2*N],y[2*N];

void level(int i)
{
    int j=tata[i];
    if(lev[j]==0)
        level(j);
    lev[i]=lev[j]+1;
}

void initarb()
{
    int i,j;
    for(i=2;i<=n;i++)
    {
       j=tata[i];
       urm[i]=prim[j];
       prim[j]=i;
    }
}

void dfs(int k)
{
     int j;
     x[m]=lev[k];y[m]=k;
     poz[k]=m;
     m++;
     j=prim[k];
     while(j)
     {
         dfs(j);
         x[m]=lev[k];y[m]=k; m++;
         j=urm[j];
     }

}


void rmqi()
{
    int i,j,k;
    k=0;j=2;
    for(i=1;i<m;i++)
    {
        if(i==j)
        {
            k++;j*=2;
        }
        lg2[i]=k;
    }
    for(i=1;i<m;i++)
        a[i][0]=i;

    for(j=1,k=1;j<m;j*=2,k++)
       for(i=1;i<=m-j;i++)
          if(x[a[i][k-1]]<=x[a[i+j][k-1]])
              a[i][k]=a[i][k-1];
           else
              a[i][k]=a[i+j][k-1];
}

int min(int p,int q)
{
    if(p<q)
        return p;
    else
        return q;
}

int rmq(int i,int j)
{
    int p=poz[i],q=poz[j],k,aux;
    if(p>q)
    {
        aux=p;p=q;q=aux;
    }
    k=lg2[q-p+1];j=1<<k;
    if(x[a[p][k]]<x[a[q-j+1][k]])
        return y[a[p][k]];
    else
        return y[a[q-j+1][k]];
}

void main()
{
    int i,j,k,r;
    FILE *f,*g;
    f=fopen("lca.in","r");
    g=fopen("lca.out","w");
    fscanf(f,"%d %d", &n,&r);

    for(i=2;i<=n;i++)
        fscanf(f,"%d",tata+i);

    tata[1]=0;lev[1]=1;
    for(i=2;i<=n;i++)
        if(lev[i]==0)
            level(i);

    initarb();

    m=1;
    dfs(1);

    rmqi();

    for(i=1;i<=r;i++)
    {
        fscanf(f,"%d%d",&j,&k);
        fprintf(g,"%d\n",rmq(j,k));

    }
}