Cod sursa(job #1151434)

Utilizator alexpascadiAlexandru Pascadi alexpascadi Data 24 martie 2014 09:42:18
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include <stdio.h>

using namespace std;

const int N=100001;
const int LOG=18;

int r[2*N][LOG];
int vf[N],urm[N],lst[N],v[2*N],nv=0,nivel[N],niv=0,p2[2*N],prim[N];

void dfs(int x)
{
    niv++;
    nivel[x]=niv;
    v[++nv]=x;
    int p=lst[x],y;
    while(p!=0)
    {
        y=vf[p];
        dfs(y);
        v[++nv]=x;
        p=urm[p];
    }
    niv--;
}

int main()
{
    FILE *in,*out;
    in=fopen("lca.in","r");
    out=fopen("lca.out","w");
    int n,m,i,j,x,y,nr=0,p,minim,aux;

    fscanf(in,"%d%d",&n,&m);

    for(y=2;y<=n;y++)
    {
        fscanf(in,"%d",&x);
        nr++;
        vf[nr]=y;
        urm[nr]=lst[x];
        lst[x]=nr;
    }

    dfs(1);

    for(i=1;i<=nv;i++)
    {
        r[i][0]=v[i];
        for(j=1;(1<<(j-1))<i;j++)
        {
            if(nivel[r[i-(1<<(j-1))][j-1]] <= nivel[r[i][j-1]])
                r[i][j]=r[i-(1<<(j-1))][j-1];
            else
                r[i][j]=r[i][j-1];
        }
    }

    p2[1]=0;
    for(i=2;i<=nv;i++)
    {
        p2[i]=p2[i-1];
        if((1<<(p2[i]+1))==i) p2[i]++;
    }

    for(i=1;i<=nv;i++)
    {
        if(prim[v[i]]==0)
            prim[v[i]]=i;
    }

    for(i=1;i<=m;i++)
    {
        fscanf(in,"%d%d",&x,&y);
        x=prim[x];
        y=prim[y];
        if(x>y)
        {
            aux=x;
            x=y;
            y=aux;
        }
        p=p2[y-x+1];
        if(nivel[r[x+(1<<p)-1][p]]<=nivel[r[y][p]])
            minim=r[x+(1<<p)-1][p];
        else
            minim=r[y][p];
        fprintf(out,"%d\n",minim);
    }

    return 0;
}