Cod sursa(job #3349296)

Utilizator andreiiorgulescuandrei iorgulescu andreiiorgulescu Data 27 martie 2026 22:53:13
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, q, v[100005];
vector<int> g[100005], f[100005];
int t[100005], sz[100005];
int ord[100005], pos[100005], h[100005];
int rep[100005], cr;

bool cmp(int A, int B)
{
	return sz[A] > sz[B];
}

void dfs(int nod)
{
	sz[nod] = 1;
	for (auto vecin : g[nod])
	{
		if (vecin != t[nod])
		{
			t[vecin] = nod;
			h[vecin] = 1 + h[nod];
			f[nod].push_back(vecin);
			dfs(vecin);
			sz[nod] += sz[vecin];
		}
	}
	sort(f[nod].begin(), f[nod].end(), cmp);
}


void df(int nod)
{
	cr++;
	ord[cr] = nod;
	pos[nod] = cr;
	if (f[nod].empty())
		return;
	rep[f[nod][0]] = rep[nod];
	df(f[nod][0]);
	for (int i = 1; i < f[nod].size(); i++)
	{
		rep[f[nod][i]] = f[nod][i];
		df(f[nod][i]);
	}
}

int aint[400005];

void update(int nod, int l, int r, int pos, int val)
{
	if (l == r)
		aint[nod] = val;
	else
	{
		int mij = (l + r) / 2;
		if (pos <= mij)
			update(2 * nod, l, mij, pos, val);
		else
			update(2 * nod + 1, mij + 1, r, pos, val);
		aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
	}
}

int query(int nod, int l, int r, int st, int dr)
{
	if (r < st or dr < l)
		return -1;
	if (st <= l and r <= dr)
		return aint[nod];
	int mij = (l + r) / 2;
	return max(query(2 * nod, l, mij, st, dr), query(2 * nod + 1, mij + 1, r, st, dr));
}

int lca(int x, int y)
{
	if (h[x] < h[y])
		swap(x, y);
	if (rep[x] == rep[y])
		return y;
	if (h[rep[x]] > h[rep[y]])
		x = t[rep[x]];
	else
		y = t[rep[y]];
	return lca(x, y);
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	in >> n >> q;
	for (int i = 1; i <= n; i++)
		in >> v[i];
	for (int i = 1; i < n; i++)
	{
		int x, y;
		in >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	h[0] = -1;
	dfs(1);
	rep[1] = 1;
	df(1);
	for (int i = 1; i <= n; i++)
		update(1, 1, n, pos[i], v[i]);
	for (int iq = 1; iq <= q; iq++)
	{
		int tip;
		in >> tip;
		if (tip == 0)
		{
			int x, y;
			in >> x >> y;
			update(1, 1, n, pos[x], y);
		}
		else
		{
			int x, y;
			in >> x >> y;
			int l = lca(x, y);
			int ans = 0;
			while (h[x] >= h[l])
			{
				int rt = rep[x];
				if (h[rt] > h[l])
				{
					ans = max(ans, query(1, 1, n, pos[rt], pos[x]));
					x = t[rt];
				}
				else
				{
					ans = max(ans, query(1, 1, n, pos[l], pos[x]));
					break;
				}
			}
			x = y;
			while (h[x] >= h[l])
			{
				int rt = rep[x];
				if (h[rt] > h[l])
				{
					ans = max(ans, query(1, 1, n, pos[rt], pos[x]));
					x = t[rt];
				}
				else
				{
					ans = max(ans, query(1, 1, n, pos[l], pos[x]));
					break;
				}
			}
			x = y;
			out << ans << '\n';
		}
	}
	return 0;
}