Cod sursa(job #2827804)

Utilizator LucaMihaiLM10Luca Ilie LucaMihaiLM10 Data 6 ianuarie 2022 13:32:18
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb
#include <stdio.h>
#include <vector>

#define MAX_N 100000
#define MAX_LG2N 16

using namespace std;

struct nodEuler {
    int nod, depth;

    bool operator < (const nodEuler &a) const {
        return depth < a.depth;
    }
};

int eulerSize;
int poz[MAX_N], lg2[MAX_N + 1];
nodEuler euler[2 * MAX_N], rmq[MAX_N][MAX_LG2N + 1];
vector <int> son[MAX_N];

void dfs( int nod, int depth ) {
    int i;

    euler[eulerSize] = { nod, depth };
    poz[nod] = eulerSize;
    eulerSize++;
    for ( i = 0; i < son[nod].size(); i++ ) {
        dfs( son[nod][i], depth + 1 );
        euler[eulerSize] = { nod, depth };
        poz[nod] = eulerSize;
        eulerSize++;
    }
}

void initLCA() {
    int i, j;

    dfs( 0, 0 );

    for ( i = 0; i < eulerSize; i++ )
        rmq[i][0] = euler[i];
    for ( j = 1; (1 << j) <= eulerSize; j++ ) {
        for ( i = 0; i + (1 << j) < eulerSize; i++ ) {
            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 = 2; i <= eulerSize; i++ )
        lg2[i] = lg2[i / 2] + 1;
}

int queryLCA( int x, int y ) {
    int s, d, aux, j;

    s = poz[x];
    d = poz[y];
    if ( s > d ) {
        aux = s;
        s = d;
        d = aux;
    }

    j = lg2[d - s + 1] ;
    if ( rmq[s][j] < rmq[d - (1 << j) + 1][j] )
        return rmq[s][j].nod;
    return rmq[d - (1 << j) + 1][j].nod;
};

int main() {
    FILE *fin, *fout;
    int n, m, a, b, i;

    fin = fopen( "lca.in", "r" );

    fscanf( fin, "%d%d", &n, &m );
    for ( i = 1; i < n; i++ ) {
        fscanf( fin, "%d", &a );
        a--;
        son[a].push_back( i );
    }

    initLCA();

    fout = fopen( "lca.out", "w" );

    for ( i = 0; i < m; i++ ) {
        fscanf( fin, "%d%d", &a, &b );
        a--;
        b--;

        fprintf( fout, "%d\n", queryLCA( a, b ) + 1 );
    }

    fclose( fin );
    fclose( fout );

    return 0;
}