Cod sursa(job #1068864)

Utilizator Catalina_BrinzaBrinza Catalina Catalina_Brinza Data 28 decembrie 2013 21:13:10
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include <fstream>
#include <math.h>
#define qu 100001
int a[17][qu];
int nivel[qu];
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");


int log2(int x)
{int q=1,n=0;
    while (q<=x)
    {
        q=q<<1;
        n++;
    }
    return n-1;
}

int nivelare(int x,int p)
{int l;
    
        while (p!=0)
        {l=log2(p);
            x=a[l][x];
            if (x==0) return x;
            p-=(1<<l);}
            return x;
        }

int cautare(int x,int y,int st, int dr)
{int mij, xj, yj;
    mij=(dr-st)/2+st+1;

    xj=nivelare(x,mij-1);
    //g<<st<<dr<<mij;
    yj=nivelare(y,mij-1);
    //g<<st<<' '<<dr<<' '<<mij<<' '<<xj<<' '<<yj<<' '<<a[0][yj]<<' '<<a[0][xj]<<"\n";
    if (a[0][yj]==a[0][xj] && xj!=yj) return a[0][yj];
    else if (xj!=yj)
         return cautare(x,y,mij+1,dr);
    else return cautare(x,y,st,mij-1);
    return 0;
}

int main()
{int n,m,i,l,x,y,d,mij,j,p;
    f>>n>>m;
    nivel[1]=0;
    a[0][1]=0;
    for (i=2;i<=n;++i)
    {
        f>>a[0][i];
        nivel[i]=nivel[a[0][i]]+1;
    }

    for (i=1;(1<<i)<=n;i++)
        for (j=1;j<=n;j++) a[i][j]=a[i-1][a[i-1][j]];
    //for (i=2;i<=n;++i) g<<a[0][i]<<' ';
    for (i=0;i<m;++i)
    {
        f>>x>>y;
        p=nivel[x]-nivel[y];
        if (p<0) y=nivelare(y,abs(p));
        else if (p>0) x=nivelare(x,p);
        p=nivel[x];
 
        if (x==y) g<<x<<' '<<"\n";
        else
        g<<cautare(x,y,0,p)<<"\n";
    }
    

    return 0;
}