Cod sursa(job #3296039)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 10 mai 2025 21:31:37
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
#include <stdio.h>

#include <vector>
#include <algorithm>

struct Splay {
  struct Node {
    int c[2], par;
    int key, flip, path;
    Node(): par(0), key(0), flip(false), path(0) { c[0] = c[1] = 0; }
  };

  std::vector<Node> t;
  Splay( int n ): t(n + 1) {}

  void push( int u ) {
    if( !t[u].flip ) return;
    std::swap( t[u].c[0], t[u].c[1] );
    int left = t[u].c[0], right = t[u].c[1];
    if( left ) t[left].flip ^= true;
    if( right ) t[right].flip ^= true;
    t[u].flip = false;
  }

  void pull( int u ) {
    t[u].path = std::max( t[t[u].c[0]].path, std::max( t[u].key, t[t[u].c[1]].path ) ); 
  }

  int side( int x ) {
    int y = t[x].par;
    if( t[y].c[0] == x ) return 0;
    if( t[y].c[1] == x ) return 1;
    return -1;
  }

  void link( int u, int v, int side ) {
    if( v ) t[v].par = u;
    if( u && ~side ){
      t[u].c[side] = v;
      pull( u );
    }
  }

  void zig( int x ) {
    int y = t[x].par, sx = side( x );
    int mij = t[x].c[!sx], up = t[y].par, sy = side( y );

    link( y, mij, sx );
    link( x, y, !sx );
    link( up, x, sy );
  }

  void splay( int x ) {
    while( ~side( x ) ){
      int y = t[x].par;
      if( !~side( y ) ){
        push( y );
        push( x );
        zig( x );
        return;
      }

      int z = t[y].par;
      push( z );
      push( y ); 
      push( x );
     
      zig( side( x ) == side( y ) ? y : x );
      zig( x );
    }
  }
};

struct LinkCut : Splay {
  LinkCut( int n ): Splay(n) {}

  void expose( int u ) {
    int uu = u, joe = 0;
    while( u ){
      splay( u );
      push( u );

      t[u].c[1] = joe;
      pull( u );

      joe = u;
      u = t[u].par;
    }

    splay( uu );
  }

  void reroot( int u ) {
    expose( u );
    t[u].flip ^= true;
  }

  void Link( int a, int b ) {
    expose( a );
    reroot( b );
    t[b].par = a;
  }

  int Path( int a, int b ) {
    reroot( a );
    expose( b );
    return t[b].path;
  }

  void Update( int u, int val ) {
    expose( u );
    t[u].key = val;
    pull( u );
  }
};

int main() {
  FILE *fin = fopen( "heavypath.in", "r" );
  FILE *fout = fopen( "heavypath.out", "w" );

  int n, q;
  fscanf( fin, "%d%d", &n, &q );

  LinkCut zile(n);
  for( int i = 1; i <= n; i++ ){
    int val;
    fscanf( fin, "%d", &val );
    zile.Update( i, val );
  }

  for( int i = 1; i < n; i++ ){
    int a, b;
    fscanf( fin, "%d%d", &a, &b );
    zile.Link( a, b );
  }

  for( int i = 0; i < q; i++ ){
    int task, x, y;
    fscanf( fin, "%d %d%d", &task, &x, &y );

    if( task == 0 )
      zile.Update( x, y );
    else
      fprintf( fout, "%d\n", zile.Path( x, y ) );
  }

  fclose( fin );
  fclose( fout );
  return 0;
}