Cod sursa(job #1680397)

Utilizator rughibemBelcineanu Alexandru Ioan rughibem Data 8 aprilie 2016 18:44:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include<cstdio>
#include<algorithm>
#include<vector>
#define MAXN 100010
#define logMAXN 25
FILE *f=fopen("lca.in","r"), *g=fopen("lca.out","w");

using namespace std;

vector <int> v[MAXN];

struct Informatii{ int nod, niv; } a[2*MAXN], RMQ[logMAXN][2*MAXN];

int N, Q, A = 0, fp[MAXN], loga[2*MAXN], put[logMAXN];

    // fp = prima pozitie

void DFS( int nod, int niv ){
int i;

    A ++;
    a[A].niv = niv;
    a[A].nod = nod;
    fp[nod] = A;

    for(i=0;i<v[nod].size();i++){

        DFS( v[nod][i], niv+1 );

        A ++;
        a[A].niv = niv;
        a[A].nod = nod;

    }
}

void Citire(){
int i, x;

    fscanf(f,"%d %d\n",&N,&Q);

    for(i=2;i<=N;i++){

        fscanf(f,"%d",&x);
        v[x].push_back(i);

    }

    DFS(1,0);

}

void Initializari(){
int i;

    loga[1] = 0;
    for(i=2;i<=A;i++)
        loga[i] = loga[i/2] + 1;

    put[0] = 1;
    for(i=1;i<=loga[A];i++)
        put[i] = 2*put[i-1];

}

void CreareRMQ(){
int i, j;

    Initializari();

    for(i=1;i<=A;i++)
        RMQ[0][i] = a[i];

    for(i=1;i<=loga[A];i++)
        for(j=1;j+put[i]-1<=A;j++)
            if( RMQ[i-1][j].niv < RMQ[i-1][ j + put[i-1] ].niv )
                RMQ[i][j] = RMQ[i-1][j];
            else
                RMQ[i][j] = RMQ[i-1][ j + put[i-1] ];

}

void Query(){
int q, x, y, p1, p2, lg, pu;

    for(q=1;q<=Q;q++){

        fscanf(f,"%d %d\n",&x,&y);

        p1 = fp[x];
        p2 = fp[y];

        if( p1 > p2 )
            swap(p1,p2);

        lg = loga[ p2-p1+1 ];
        pu = put[lg];

        if( RMQ[lg][p1].niv < RMQ[lg][p2-pu+1].niv )
            fprintf(g,"%d\n", RMQ[lg][p1].nod );
        else
            fprintf(g,"%d\n", RMQ[lg][p2-pu+1].nod );

    }

}

int main(){

    Citire();
    CreareRMQ();
    Query();

return 0;
}