Cod sursa(job #1394003)

Utilizator koroalinAlin Corodescu koroalin Data 19 martie 2015 22:04:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 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 niv);
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,0);
    for (i=1; i<=nre; i++)
        rmq[i][0]=i;
    for (j=1; (1<<j)<nre; j++)
        for (i=1; i<= nre-(1<<j)+1; i++)
        {
            L=(1<<(j-1));
            if (nivel[PE[rmq[i][j-1]]]<nivel[PE[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 niv)
{
    int i;
    nivel[nod]=niv;
    uz[nod]=1;
    PE[++nre]=nod;
    ind[nod]=nre;
    for (i=0; i<G[nod].size(); i++)
    {
        if (!uz[G[nod][i]])
        {
            dfs(G[nod][i],niv+1);
            PE[++nre]=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[PE[rmq[x][L]]]<nivel[PE[rmq[x+l][L]]]) return PE[rmq[x][L]];
    else return PE[rmq[x+l][L]];
}
int logaritm(int x)
{
    int p=0;
    while ((1<<p)<=x) p++;
    return p-1;
}