Cod sursa(job #1410783)

Utilizator koroalinAlin Corodescu koroalin Data 31 martie 2015 11:51:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <cstdio>
#include <vector>
#define NMAX 100005
using namespace std;
FILE* fin=fopen("lca.in","r");
FILE* fout=fopen("lca.out","w");
vector <int> G[NMAX];
int uz[NMAX],PE[10*NMAX],ind[NMAX],nivel[NMAX],rmq[4*NMAX][20],nre;
int n,m;
void dfs(int nod);
int query(int x,int y);
int logaritm(int x);
int main()
{
    int i,x,j,y,L;
    fscanf(fin,"%d %d",&n,&m);
    for (i=2; i<=n; i++)
    {
        fscanf(fin,"%d",&x);
        G[x].push_back(i);
       // G[i].push_back(x);
    }
    dfs(1);
//    for (i=1; i<=nre; i++)
//        rmq[i][0]=PE[i];
    for (j=1; (1<<j)<nre; j++)
        for (i=1; i<= nre-(1<<j)+1; i++)
        {
            L=(1<<(j-1));
            if (nivel[rmq[i][j-1]]<nivel[rmq[i+L][j-1]]) rmq[i][j]=rmq[i][j-1];
            else rmq[i][j]=rmq[i+L][j-1];
        }
    for (i=1; i<=m; i++)
    {
        fscanf(fin,"%d %d",&x,&y);
        fprintf(fout,"%d\n",query(ind[x],ind[y]));
    }
    return 0;
}
void dfs(int nod)
{
    int i;
    uz[nod]=1;
    //PE[++nre]=nod;
    rmq[++nre][0]=nod;
    ind[nod]=nre;
    for (i=0; i<G[nod].size(); i++)
    {
        //if (!uz[G[nod][i]])
       // {
            nivel[G[nod][i]]=nivel[nod]+1;
            dfs(G[nod][i]);
            //PE[++nre]=nod;
            rmq[++nre][0]=nod;
       // }
    }
}
int query(int x,int y)
{
    int L,l,dif;
    if (x>y) swap(x,y);
    dif=y-x+1;
    L=logaritm(dif);
    l=dif-(1<<L);
    if (nivel[rmq[x][L]]<nivel[rmq[x+l][L]]) return rmq[x][L];
    else return rmq[x+l][L];
}
int logaritm(int x)
{
    int p=0;
    while ((1<<p)<=x) p++;
    return p-1;
}