Cod sursa(job #2786624)

Utilizator LucaMihaiLM10Luca Ilie LucaMihaiLM10 Data 21 octombrie 2021 12:25:10
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <stdio.h>
#include <vector>

#define MAX_N 100000
#define MAX_LG2N 17

using std::vector;

struct nodEuler {
    int nod, depth;
};

int eulerSize;
int poz[MAX_N], lg2[2 * MAX_N + 1];
nodEuler euler[2 * MAX_N], rmq[2 * 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++;
    }
}

nodEuler queryRMQ( int s, int d ) {
    int j = lg2[d - s + 1];

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

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

    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 );
    }

    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 < eulerSize; i++ ) {
            if ( rmq[i][j - 1].depth < rmq[i + (1 << (j - 1))][j - 1].depth )
                rmq[i][j] = rmq[i][j - 1];
            else
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
        }
    }

    for ( i = 1; i <= 2 * n; i++ )
        lg2[i] = (1 << (lg2[i - 1] + 1)) == i ? lg2[i - 1] + 1 : lg2[i - 1];

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

    for ( i = 0; i < m; i++ ) {
        fscanf( fin, "%d%d", &a, &b );
        a--;
        b--;
        fprintf( fout, "%d\n", queryRMQ( poz[a], poz[b] ).nod + 1  );
    }

    fclose( fin );
    fclose( fout );

    return 0;
}