Cod sursa(job #1519201)

Utilizator andreii1Ilie Andrei andreii1 Data 6 noiembrie 2015 23:27:47
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <cstdio>
#include <vector>
#define pb push_back
#define MAXN 100010
using namespace std;

int RMQ[21][5*MAXN],NOD[2*MAXN],First[MAXN],lg[MAXN],H[2*MAXN],n,t,a,b;
vector<int> V[MAXN];

void dfs(int nod,int lvl)
{
    int i;
    H[++H[0]]=lvl;
    NOD[H[0]]=nod;
    First[nod]=H[0];
    for(vector<int>::iterator it=V[nod].begin();it!=V[nod].end();++it)
    {
        dfs(*it,lvl+1);
        H[++H[0]]=lvl;
        NOD[H[0]]=nod;
    }
}

int query(int a,int b)
{
    int q=lg[b-a];
    if(H[RMQ[q][a]]<H[RMQ[q][b-(1<<q)+1]])return RMQ[q][a];
    return RMQ[q][b-(1<<q)+1];
}

int main()
{
    int i,j,x,aux=1,sol;
    FILE *f=fopen("lca.in","r");
    FILE *g=fopen("lca.out","w");
    fscanf(f,"%d %d",&n,&t);
    for(i=2;i<=n;i++)
    {
        fscanf(f,"%d",&x);
        V[x].pb(i);
    }
    dfs(1,0);
    lg[1]=0;
    RMQ[0][1]=1;
    for(i=2;i<=H[0];i++){lg[i]=lg[i/2]+1;RMQ[0][i]=i;}
    for(i=1,aux=1;aux<=H[0];i++)
    {
        aux*=2;
        for(j=1;j<=H[0];j++)
        {
            RMQ[i][j]=RMQ[i-1][j];
            if(H[RMQ[i][j]]>H[RMQ[i-1][j+aux/2]]) RMQ[i][j]=RMQ[i-1][j+aux/2];
        }
    }
    for(i=1;i<=t;i++)
    {
        fscanf(f,"%d %d",&a,&b);
        a=First[a];
        b=First[b];
        if(a>b)swap(a,b);
        sol=query(a,b);
        fprintf(g,"%d\n",NOD[sol]);
    }
    //for(i=1;i<=RMQ[0][0];i++)printf("%d ",RMQ[0][i]);
    fclose(f);
    fclose(g);
    return 0;
}