Cod sursa(job #3224228)

Utilizator Tibi201eweREWR Tibi201 Data 14 aprilie 2024 22:54:49
Problema Lowest Common Ancestor Scor 10
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.56 kb
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100000
#define MAXN2P2 (1024*256)
#define NIL -1
#define INFINITE 2147483647

int next[MAXN],fChild[MAXN];
int k,euler[2*MAXN],poz[MAXN]; // Parcurgere a arborelui
int v[2*MAXN2P2],stramos[2*MAXN2P2], nP2;   // A int pt array-ul euler

void Parcurgere(int node, int h){
    v[nP2+k]=h;
    stramos[nP2+k]=node;
    poz[node]=k;
    euler[k++]=node;
    while(fChild[node]!=NIL){
        Parcurgere(fChild[node], h+1);
        v[nP2+k]=h;
        stramos[nP2+k]=node;
        euler[k++]=node;
        fChild[node]=next[fChild[node]];
    }
}

void build(){
    int i;
    for(i=nP2-1; i>=1; i--){
        if(v[i*2]<v[i*2+1]){
            v[i]=v[i*2];
            stramos[i]=stramos[i*2];
        }else{
            v[i]=v[i*2+1];
            stramos[i]=stramos[i*2+1];
        }
    }
}

int minim(int st, int dr){
    int size=1,i,min=INFINITE,mini=0;
    //to top
    i=st+nP2;
    while(dr-st+1>size){
        if(v[i]<min){
            min=v[i];
            mini=stramos[i];
        }
        if((i&1)==0){   //left child
            i/=2;
            size*=2;
        }else{
            i=(i+1)/2;
            st+=size;
            size*=2;
        }
    }
    if(dr-st+1==size){
        if(v[i]<min){
            min=v[i];
            mini=stramos[i];
        }
    }else{
        while(dr-st+1!=size){
            if(dr-st+1>size){
                if(v[i]<min){
                    min=v[i];
                    mini=stramos[i];
                }
                i=(i+1)*2;
                st+=size;
                size/=2;
            }else{
                i=i*2;
                size/=2;
            }
        }
        if(v[i]<min){
            min=v[i];
            mini=stramos[i];
        }
    }
    return mini;
}

int main()
{
    FILE *fin, *fout;
    int m,parent,n,i,st,dr;
    fin=fopen("lca.in", "r");
    fscanf(fin, "%d%d", &n, &m);
    nP2=1;
    while(nP2<n)
        nP2*=2;
    for(i=0; i<n; i++){
        fChild[i]=NIL;
    }
    for(i=1; i<n; i++){
        fscanf(fin, "%d", &parent);
        next[i]=fChild[parent-1];
        fChild[parent-1]=i;
    }
    Parcurgere(0, 1);
    build();
    fout=fopen("lca.out", "w");
    for(i=0; i<m; i++){
        fscanf(fin, "%d%d", &st, &dr);
        st=poz[st-1];
        dr=poz[dr-1];
        if(st>dr){
            parent=st;
            st=dr;
            dr=parent;
        }
        fprintf(fout, "%d\n", minim(st, dr)+1);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}