Cod sursa(job #3226567)

Utilizator Ana_22Ana Petcu Ana_22 Data 21 aprilie 2024 23:51:38
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 200001
#define INF 10000000
using namespace std;

int n, dpth;
int poz[NMAX];
struct str{
    int ad, node;
} lvl[NMAX];
vector <int> sons[NMAX];

ifstream fin( "lca.in" );
ofstream fout( "lca.out" );

struct arbint {
    int aint[4*NMAX];
    void build( int node, int l, int r ) {
        if( l == r ) {
            aint[node] = l;
            return;
        }
        
        int mijl = ( l + r ) / 2;
        int lson = 2 * node;
        int rson = 2 * node + 1;
        
        build( lson, l, mijl );
        build( rson, mijl + 1, r );
        
        if( lvl[aint[lson]].ad < lvl[aint[rson]].ad )
            aint[node] = aint[lson];
        else
            aint[node] = aint[rson];
    }
    
    int query( int node, int l, int r, int ql, int qr ) {
        if( l >= ql && r <= qr )
            return aint[node];
        
        int rez = NMAX, mini = INF;
        int mijl = ( l + r ) / 2;
        int lson = 2 * node;
        int rson = 2 * node + 1;
        
        if( ql <= mijl ) {
            int idk = query( lson, l, mijl, ql, qr );
            if( lvl[idk].ad < mini ) {
                mini = lvl[idk].ad;
                rez = idk;
            }
        }
        if( mijl < qr ) {
            int idk = query( rson, mijl + 1, r, ql, qr );
            if( lvl[idk].ad < mini ) {
                mini = lvl[idk].ad;
                rez = idk;
            }
        }
        
        return rez;
    }
} my_aint;

void dfs_euler( int node, int curr_lvl ) {
    poz[node] = dpth;
    lvl[poz[node]] = { curr_lvl, node };
    dpth++; // pun node in parcurgerea euler
    for( unsigned int i = 0; i < sons[node].size(); i++ ) {
        int son = sons[node][i];
        dfs_euler( son, curr_lvl + 1 );
        lvl[dpth] = { curr_lvl, node };
        dpth++; // pun node din nou in parcurgerea euler, dupa fiecare fiu
    }
}

int main() {
    int parinte, q, x, y;
    fin >> n >> q;
    for( int i = 2; i <= n; i++ ) {
        fin >> parinte;
        sons[parinte].push_back( i );
    }
    for( int i = 0; i <= 2 * n; i++ )
        lvl[i].ad = INF;
    dpth = 1;
    dfs_euler( 1, 1 );
    my_aint.build( 1, 1, dpth );
    for( ; q; q-- ) {
        fin >> x >> y;
        if( poz[x] > poz[y] )
            swap( x, y );
        fout << lvl[my_aint.query( 1, 1, dpth, poz[x], poz[y] )].node << '\n';
    }
    return 0;
}