Cod sursa(job #3179149)

Utilizator angelaAngela Visuian angela Data 3 decembrie 2023 07:48:04
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

const int NMAX = 100001;

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

int n, q;
int val[NMAX], level[NMAX], father[NMAX];  
int tree[4 * NMAX];    
int weight[NMAX];      
int heavy_son[NMAX];   
int head[NMAX];        
int pos[NMAX];         
int position;          
vector<int> adj[NMAX];

void ReadGraph();
void Solve(); 

void Dfs(int x);
void Decompose(int x, int h);
int Query(int x, int y);

void UpdateTree(int node, int left, int right, int pos, int val);
int Query(int node, int left, int right, int a, int b);

int main() 
{
	ReadGraph();
	Solve();
	return 0;
}

void ReadGraph() 
{
	fin >> n >> q;
	for (int i = 1; i <= n; ++i)
		fin >> val[i];

	int x, y;
	for (int i = 1; i < n; ++i) 
	{
		fin >> x >> y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
}

void Solve() 
{
	Dfs(1);
	Decompose(1, 1);

	for (int i = 1; i <= n; ++i) 
		UpdateTree(1, 1, n, pos[i], val[i]);

	int op, x, y;
	while (q--) 
	{
		fin >> op >> x >> y;
		if (op == 0) 
			UpdateTree(1, 1, n, pos[x], y);
		else
			fout << Query(x, y) << '\n';
	}
}

void Dfs(int x) 
{
	int max_weight = 0;
	weight[x] = 1;
	
	for (int son : adj[x]) 
		if (son != father[x]) 
		{
			father[son] = x;
			level[son] = level[x] + 1;		
			Dfs(son);	
			weight[x] += weight[son];

			if (weight[son] > max_weight) 
			{
				max_weight = weight[son];
				heavy_son[x] = son;
			}
		}
}
 
void Decompose(int x, int hd) 
{
	pos[x] = ++position;
	head[x] = hd;

	if (heavy_son[x]) 
		Decompose(heavy_son[x], hd);

	for (int son : adj[x]) 
		if (heavy_son[x] != son && son != father[x]) 
			Decompose(son, son); 
}

int Query(int x, int y) 
{
	int res = 0;
	
	while (head[x] != head[y]) 
	{
		if (level[head[x]] < level[head[y]]) 
			swap(x, y);
		res = max(res, Query(1, 1, n, pos[head[x]], pos[x]));
		x = father[head[x]];
	}
	
	if (level[x] > level[y]) 
		swap(x, y);

	return max(res, Query(1, 1, n, pos[x], pos[y]));
}

void UpdateTree(int node, int left, int right, int pos, int val) 
{
	if (left == right) 
	{
		tree[node] = val;
		return;
	}
	int mid = (left + right) >> 1;
	
	if (pos <= mid)
		UpdateTree(2 * node, left, mid, pos, val);
	else
		UpdateTree(2 * node + 1, mid + 1, right, pos, val);
		
	tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}

int Query(int node, int left, int right, int a, int b) 
{
	if (a <= left && right <= b) 
		return tree[node];

	int mid = (left + right) >> 1;
	int max1 = 0, max2 = 0;
	
	if (a <= mid)
		max1 = Query(2 * node, left, mid, a, b);
	if (b > mid)
		max2 = Query(2 * node + 1, mid + 1, right, a, b);
	return max(max1, max2);
}