Cod sursa(job #1238870)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 7 octombrie 2014 20:57:21
Problema Lowest Common Ancestor Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.81 kb
#include <stdio.h>
#define MAXN 100000
#define MAXNR (2*MAXN-1)
#define LOG_NR 17
int nr, lg[MAXNR+1], rmq[LOG_NR+1][MAXNR], niv[MAXNR+1], H[MAXNR+1], first[MAXN+1], val[MAXN], next[MAXN], lista[MAXN+1];
inline void precalc_log(){
    int k, i;
    k=0;
    for(i=1; i<=nr; i++){
        if(i>=(2<<k)){
            k++;
        }
        lg[i]=k;
    }
}
inline void precalc_rmq(){
    int i, j;
    for(i=1; i<=nr; i++){
        rmq[0][i]=i;
    }
    for(i=1; (1<<i)<=nr; i++){
        for(j=1; j<=nr; j++){
            if(j>=(1<<i)){
                rmq[i][j]=rmq[i-1][j];
                if(niv[rmq[i-1][j]]>niv[rmq[i-1][j-(1<<(i-1))]]){
                    rmq[i][j]=rmq[i-1][j-(1<<(i-1))];
                }
            }
        }
    }
}
void euler(int nod){
    int p;
    nr++;
    H[nr]=nod;
    niv[nr]=nod;
    first[nod]=nr;
    p=lista[nod];
    while(p!=0){
        euler(val[p]);
        nr++;
        H[nr]=nod;
        niv[nr]=nod;
        p=next[p];
    }
}
inline int lca(int a, int b){
    int aux, l, rez;
    if(a>b){
        aux=a;
        a=b;
        b=aux;
    }
    l=lg[b-a+1];
    rez=H[rmq[l][b]];
    if(niv[rmq[l][b]]>niv[rmq[l][a+(1<<l)-1]]){
        rez=H[rmq[l][a+(1<<l)-1]];
    }
    return rez;
}
int main(){
    int Q, q, i, k, x, j, n;
    FILE *fin, *fout;
    fin=fopen("lca.in", "r");
    fout=fopen("lca.out", "w");
    fscanf(fin, "%d%d", &n, &Q);
    k=0;
    for(i=2; i<=n; i++){
        fscanf(fin, "%d", &x);
        k++;
        val[k]=i;
        next[k]=lista[x];
        lista[x]=k;
    }
    euler(1);
    precalc_log();
    precalc_rmq();
    for(q=0; q<Q; q++){
        fscanf(fin, "%d%d", &i, &j);
        fprintf(fout, "%d\n", lca(first[i], first[j]));
    }
    fclose(fin);
    fclose(fout);
    return 0;
}