Cod sursa(job #1645487)

Utilizator andi12Draghici Andrei andi12 Data 10 martie 2016 12:31:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <cstdio>

using namespace std;
const int N=100005;
int lst[N],urm[2*N],vf[2*N],e[2*N],nivel[2*N],vizitat[N],prim[N],lg[2*N];
int rmq[19][2*N];
int p,nre,niv;
void ad(int x,int y)
{
    p++;
    vf[p]=y;
    urm[p]=lst[x];
    lst[x]=p;
}
void dfs(int x)
{
    int y,poz;
    poz=lst[x];
    nre++;
    e[nre]=x;
    nivel[nre]=niv;
    vizitat[x]=1;
    prim[x]=nre;
    while(poz!=0)
    {
        y=vf[poz];
        if(vizitat[y]==0)
        {
            niv++;
            dfs(y);
            niv--;
            nre++;
            e[nre]=x;
            nivel[nre]=niv;
        }
        poz=urm[poz];
    }
}
int min(int a,int b)
{
    if(nivel[prim[a]]<=nivel[prim[b]])
        return a;
    else
        return b;
}
int main()
{
    FILE *in,*out;
    in=fopen("lca.in","r");
    out=fopen("lca.out","w");
    int n,m,i,y,j,pow,a,b,aux,dif,l,ras;
    fscanf(in,"%d%d",&n,&m);
    for(i=1;i<n;i++)
    {
        fscanf(in,"%d",&y);
        ad(i+1,y);
        ad(y,i+1);
    }
    dfs(1);
    for(i=1;i<=2*n;i++)
        rmq[0][i]=e[i];
    for(i=1;1<<i<=2*n;i++)
    {
        for(j=1<<i;j<=2*n;j++)
        {
            pow=1<<(i-1);
            rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j-pow]);
        }
    }
    for(i=1;i<=2*n;i++)
        lg[i]=lg[i/2]+1;
    for(i=1;i<=2*n;i++)
        lg[i]--;
    for(i=1;i<=m;i++)
    {
        fscanf(in,"%d%d",&a,&b);
        a=prim[a];
        b=prim[b];
        if(a>b)
        {
            aux=a;
            a=b;
            b=aux;
        }
        dif=b-a+1;
        l=lg[dif];
        pow=1<<l;
        ras=min(rmq[l][b],rmq[l][a+pow-1]);
        fprintf(out,"%d\n",ras);
    }
    return 0;
}