Cod sursa(job #1398238)

Utilizator casuneanu.andreiCasuneanu Andrei Dan casuneanu.andrei Data 24 martie 2015 03:37:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <cstdio>
#include <vector>
using namespace std;
#define NMAX 100005
#define IN "lca.in"
#define OUT "lca.out"
#define pb push_back

FILE* fin=fopen(IN, "r");
FILE* fout=fopen(OUT, "w");

vector <int> G[NMAX];
int uz[NMAX],PE[10*NMAX];
int ind[NMAX],nivel[NMAX],rmq[4*NMAX][20];
int nre;
int n, m;

void dfs(int, int);
int query(int, int);
int logaritm(int);

int main(){
    fscanf(fin,"%d %d",&n, &m);
    int i, x;
    for (i=2; i<=n; ++i){
        fscanf(fin,"%d", &x);
        G[x].pb(i);
    }
    dfs(1, 0);
    for (i=1; i<=nre; ++i)
        rmq[i][0]=i;

    int j, L;
    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];
        }
    
    int y;
    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;
    int x=G[nod].size();
    for (i=0; i<x; ++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]];
    return PE[rmq[x+l][L]];
}

int logaritm(int x){
    int p=0;
    while ((1<<p)<=x) ++p;
    return p-1;
}