Cod sursa(job #3290720)

Utilizator CosminaneBoac Mihai Cosmin Cosminane Data 31 martie 2025 17:59:20
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.58 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int aint[400020], v[100005], height[100005], marime[100005], parinte[100005], nr_lant[100005], decalaje[100005], nr;
vector <int> muchii[100005], lant[100005];
void dfs(int x, int lvl){
	int i, y, max_marime;
	marime[x] = 1;
	height[x] = lvl;
	max_marime = 0;
	nr_lant[x] = -1;
	for( i = 0; i < muchii[x].size(); i++ ){
		y = muchii[x][i];
		parinte[y] = x;
		dfs( y, lvl + 1 );
		if( marime[y] > max_marime ){
			max_marime = marime[y];
			nr_lant[x] = nr_lant[y];
		}
	}
	if( nr_lant[x] == -1 ){
		nr_lant[x] = nr;
		nr++;
	}
	lant[nr_lant[x]].push_back( x );
}
void build(int nod, int st, int dr, int decalaj, int lant_cur){
	int mij = ( st + dr ) / 2;
	//cout << nod << ' ' << st << ' ' << dr << ' ' << decalaj << ' ' << lant_cur << '\n';
	if( st == dr ){
		aint[nod + decalaj] = v[lant[lant_cur][st]];
	}
	else{
		build( nod * 2, st, mij, decalaj, lant_cur );
		build( nod * 2 + 1, mij + 1, dr, decalaj, lant_cur );
		aint[nod + decalaj] = max( aint[nod * 2 + decalaj], aint[nod * 2 + 1 + decalaj] );
	}
}
void heavy_light_decomp(){
	int i;
	nr = 0;
	dfs( 1, 1 );
	for( i = 0; i < nr; i++ ){
		reverse( lant[i].begin(), lant[i].end() );
		/*for( int j = 0; j < lant[i].size(); j++ ){
			cout << lant[i][j] << ' ';
		}
		cout << '\n';*/
		if( i > 0 ){
			decalaje[i] = decalaje[i - 1] + lant[i - 1].size() * 4;
		}
		build( 1, 0, lant[i].size() - 1, decalaje[i], i );
	}
	//cout << "GATA\n";
}
void update(int nod, int st, int dr, int poz, int val, int decalaj){
	int mij = ( st + dr ) / 2;
	if( st == dr ){
		aint[nod + decalaj] = val;
	}
	else{
		if( poz <= mij ){
			update( nod * 2, st, mij, poz, val, decalaj );
		}
		else{
			update( nod * 2 + 1, mij + 1, dr, poz, val, decalaj );
		}
		aint[nod + decalaj] = max( aint[nod * 2 + decalaj], aint[nod * 2 + 1 + decalaj] );
	}
}
int query(int nod, int st, int dr, int x, int y, int decalaj){
	int mij = ( st + dr ) / 2, r;
	if( x <= st && dr <= y ){
		return aint[nod + decalaj];
	}
	r = 0;
	if( x <= mij ){
		r = max( query( nod * 2, st, mij, x, y, decalaj ), r );
	}
	if( y > mij ){
		r = max( query( nod * 2 + 1, mij + 1, dr, x, y, decalaj ), r );
	}
	return r;
}
int solve(int t, int x, int y){
	int r;
	if( t == 0 ){
		update( 1, 0, lant[nr_lant[x]].size() - 1, height[x] - height[lant[nr_lant[x]].front()], y, decalaje[nr_lant[x]] );
	}
	else{
		r = 0;
		while( 1 ){
			//cout << x << ' ' << y << ' ' << height[lant[nr_lant[x]].front()] << ' ' << height[lant[nr_lant[y]].front()] << '\n';
			if( nr_lant[x] == nr_lant[y] ){
				if( height[x] > height[y] ){
					swap(x, y);
				}
				r = max(query(1, 0, lant[nr_lant[x]].size() - 1, height[x] - height[lant[nr_lant[x]].front()], height[y] - height[lant[nr_lant[x]].front()], decalaje[nr_lant[x]]), r);
				return r;
			}
			if( height[lant[nr_lant[x]].front()] < height[lant[nr_lant[y]].front()] ){
				swap( x, y );
			}
			r = max( query( 1, 0, lant[nr_lant[x]].size() - 1, 0, height[x] - height[lant[nr_lant[x]].front()], decalaje[nr_lant[x]] ), r );
			x = parinte[lant[nr_lant[x]].front()];
		}
	}
}
int main(){
	int n, m, i, t, x, y;
	ifstream fin( "heavypath.in" );
	ofstream fout( "heavypath.out" );
	fin >> n >> m;
	for( i = 1; i <= n; i++ ){
		fin >> v[i];
	}
	for( i = 1; i <= n - 1; i++ ){
		fin >> x >> y;
		if( x > y ){
			swap( x, y );
		}
		muchii[x].push_back( y );
	}
	heavy_light_decomp();
	for( i = 0; i < m; i++ ){
		fin >> t >> x >> y;
		x = solve( t, x, y );
		if( t == 1 ){
			fout << x << '\n';
		}
	}
	return 0;
}