Cod sursa(job #1982867)

Utilizator rares1012Rares Cautis rares1012 Data 20 mai 2017 14:13:09
Problema Lowest Common Ancestor Scor 30
Compilator c Status done
Runda Arhiva educationala Marime 1.82 kb
#include <stdio.h>
#include <stdlib.h>
#define N 100001


int t[N];

int f[N][2];

int lst[N];

int e[2*N-1][2];

int eu=0;

int ad[N];

int rmq[2*N-1][18];

void euler(int k)
{
    int i=lst[k];
    e[eu][0]=k;
    printf("%d ",k);
    eu++;
    while(i!=0){
        euler(f[i][0]);
        i=f[i][1];
    }
    e[eu][0]=t[k];
    printf("%d ",t[k]);
    eu++;
}

int main()
{
    int n,q,i,k=0,j,a,b,pozi,pozj,p,c;
    FILE*fi,*fo;
    fi=fopen("lca.in","r");
    fo=fopen("lca.out","w");
    fscanf(fi,"%d%d",&n,&q);
    ad[1]=0;
    for(i=2;i<=n;i++){
        fscanf(fi,"%d",&t[i]);
        ad[i]=ad[t[i]]+1;
        k++;
        f[k][0]=i;
        f[k][1]=lst[t[i]];
        lst[t[i]]=k;
    }
    euler(1);
    printf("\n\n\n");
    eu--;
    for(i=0;i<eu;i++){
        e[i][1]=ad[e[i][0]];
    }
    for(i=0;i<eu;i++)
    {
        e[i][1]=ad[e[i][0]];
    }
    for(i=0;i<n*2-1;i++){
        rmq[i][0]=e[i][1];
        for(j=1;(1<<j)<=i;j++)
        {
            if(rmq[i][j-1]<rmq[i-(1<<(j-1))][j-1])
                rmq[i][j]=rmq[i][j-1];
            else rmq[i][j]=rmq[i-(1<<(j-1))][j-1];
        }
    }
    for(i=0;i<q;i++)
    {
        fscanf(fi,"%d%d",&a,&b);
        if(a!=b){
        pozi=0;
        while(e[pozi][0]!=a)
            pozi++;
        pozj=0;
        while(e[pozj][0]!=b)
            pozj++;
        if(pozj<pozi){
            pozj+=pozi;
            pozi=pozj-pozi;
            pozj=pozj-pozi;
        }
        p=1;
        c=0;
        while(p<=pozj-pozi){
            p*=2;
            c++;
        }
        c--;
        p/=2;
        if(rmq[pozj][c]<rmq[pozi+p][c])
            p=rmq[pozj][c];
        else p=rmq[pozi+p][c];
        j=pozi;
        while(e[j][1]>p && j<=pozj)
            j++;
        fprintf(fo,"%d\n",e[j][0]);}
        else fprintf(fo,"%d\n",a);
    }
    fclose(fi);
    fclose(fo);
    return 0;
}