Cod sursa(job #2835148)

Utilizator vladburacBurac Vlad vladburac Data 18 ianuarie 2022 10:05:50
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 kb
#include <iostream>
#include <vector>
using namespace std;
#define NMAX 32000
#define MAXLOG 16

vector <int> children[NMAX+1];
int puncte[NMAX+1];
int logs[2*NMAX];
int first_app[NMAX+1], level[NMAX+1];
int rmq[MAXLOG][2*NMAX];
int euler[2*NMAX];
int eulerSize;

void dfs( int node, int lvl ) {
  level[node] = lvl;
  first_app[node] = eulerSize;
  euler[eulerSize] = node;
  eulerSize++;
  for( auto i: children[node] ) {
    dfs( i, lvl + 1 );
    euler[eulerSize++] = node;
  }
}

int f( int a, int b ) {
  if( level[a] < level[b] )
    return a;
  else
    return b;
}

int main() {
  FILE *fin, *fout;
  int n, m, a, b, i, j, len, maxi, ca, cb, first, second, lca;
  fin = fopen( "concurs.in", "r" );
  fscanf( fin, "%d%d", &n, &m );
  for( i = 1; i <= n; i++ )
    fscanf( fin, "%d", &puncte[i] );
  for( i = 1; i < n; i++ ) {
    fscanf( fin, "%d%d", &a, &b );
    children[a].push_back(b);
  }
  dfs( 1, 0 );
  logs[1] = 0;
  for( i = 2; i <= eulerSize; i++ )
    logs[i] = logs[i/2] + 1;

  for( j = 0; j < eulerSize; j++ )
    rmq[0][j] = euler[j];
  for( i = 1; ( 1 << i ) <= eulerSize; i++ ) {
    for( j = 0; j + ( 1 << i ) <= eulerSize; j++ )
      rmq[i][j] = f( rmq[i-1][j], rmq[i-1][j + ( 1 << ( i - 1 ) )] );
  }

  maxi = 0;
  for( i = 0; i < m; i++ ) {
    fscanf( fin, "%d%d", &a, &b );
    ca = a;
    cb = b;
    a = first_app[a];
    b = first_app[b];
    if( a > b )
      swap( a, b );
    len = b - a + 1;
    lca = f( rmq[logs[len]][a], rmq[logs[len]][b - ( 1 << logs[len] ) + 1] );
    if( puncte[lca] > maxi ) {
      maxi = puncte[lca];
      first = ca;
      second = cb;
    }
    else if( puncte[lca] == maxi ) {
      if( ca < first ) {
        first = ca;
        second = cb;
      }
      else if( ca == first ) {
        if( cb < second ) {
          second = cb;
        }
      }
    }
  }
  fclose( fin );
  fout = fopen( "concurs.out", "w" );
  fprintf( fout, "%d %d %d", maxi, first, second );
  fclose( fout );
  return 0;
}