Mai intai trebuie sa te autentifici.
Cod sursa(job #3147229)
Utilizator | Data | 24 august 2023 22:51:53 | |
---|---|---|---|
Problema | Heavy Path Decomposition | Scor | 100 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva educationala | Marime | 2.86 kb |
#include <stdio.h>
#include <vector>
#define magic_sauce inline __attribute__((always_inline))
magic_sauce int max( int a, int b ){ return a > b ? a : b; }
const int MAXN = 1e5;
const int MAX_AINT = 1 << 17;
std::vector<int> adj[MAXN];
int dep[MAXN];
int siz[MAXN];
int par[MAXN];
int head[MAXN];
// liniarizare heavy-first
int ord[MAXN];
int time;
int aint[2 * MAX_AINT];
int aintn;
magic_sauce void aint_update( int i, int val ){
i += aintn - 1;
aint[i] = val;
while( i ){
i = (i - 1) >> 1;
aint[i] = max( aint[i * 2 + 1], aint[i * 2 + 2] );
}
}
magic_sauce int aint_query( int st, int dr ){
int ret = 0;
st += aintn - 1;
dr += aintn - 1;
if( st > dr ){
int aux = st;
st = dr;
dr = aux;
}
// stanga impara
// dreapta para
while( st < dr ){
if( !(st & 1) )
ret = max( ret, aint[st++] );
st = (st - 1) >> 1;
if( dr & 1 )
ret = max( ret, aint[dr--] );
dr = (dr - 1) >> 1;
}
if( st == dr )
ret = max( ret, aint[st] );
return ret;
}
int v[MAXN];
void init_siz( int u, int p ){
par[u] = p;
siz[u] = 1;
for( int v : adj[u] )
if( v != p ){
dep[v] = 1 + dep[u];
init_siz( v, u );
siz[u] += siz[v];
}
}
void init_heavy( int u, int p, int h ){
int maxc = -1, maxs = -1;
head[u] = h;
ord[u] = time++;
for( int v : adj[u] )
if( v != p && siz[v] > maxs ){
maxs = siz[v];
maxc = v;
}
if( maxc < 0 )
return;
init_heavy( maxc, u, h );
for( int v : adj[u] )
if( v != p && v != maxc )
init_heavy( v, u, v );
}
int heavy_query( int a, int b ){
int ret = 0;
while( head[a] != head[b] ){
if( dep[head[a]] > dep[head[b]] ){
ret = max( ret, aint_query( ord[a], ord[head[a]] ) );
a = par[head[a]];
}else{
ret = max( ret, aint_query( ord[b], ord[head[b]] ) );
b = par[head[b]];
}
}
ret = max( ret, aint_query( ord[a], ord[b] ) );
return ret;
}
int main(){
FILE *fin = fopen( "heavypath.in", "r" );
FILE *fout = fopen( "heavypath.out", "w" );
int n, q, i, a, b, task;
fscanf( fin, "%d%d", &n, &q );
for( i = 0 ; i < n ; i++ )
fscanf( fin, "%d", v + i );
for( i = 1 ; i < n ; i++ ){
fscanf( fin, "%d%d", &a, &b );
adj[a - 1].push_back( b - 1 );
adj[b - 1].push_back( a - 1 );
}
dep[0] = 0;
init_siz( 0, 0 );
time = 0;
init_heavy( 0, 0, 0 );
aintn = 1;
while( aintn < n )
aintn <<= 1;
for( i = 0 ; i < n ; i++ )
aint[aintn - 1 + ord[i]] = v[i];
for( i = aintn - 1 ; i-- ; )
aint[i] = max( aint[i * 2 + 1], aint[i * 2 + 2] );
for( ; q-- ; ){
fscanf( fin, "%d", &task );
if( task == 0 ){
fscanf( fin, "%d%d", &i, &a );
aint_update( ord[i - 1], a );
}else{
fscanf( fin, "%d%d", &a, &b );
fprintf( fout, "%d\n", heavy_query( a - 1, b - 1 ) );
}
}
fclose( fin );
fclose( fout );
return 0;
}