Cod sursa(job #2298750)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 8 decembrie 2018 14:04:23
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include <bits/stdc++.h>
using namespace std;

using Pii = pair <int, int>;

namespace HP {
	const int NMAX = 100010;
	int h[NMAX], link[NMAX], id[NMAX], tata[NMAX], g[NMAX], cnt;
	vector <int> adia[NMAX];

	int calc_g(int nod, int t) {
		g[nod] = 1;
		h[nod] = 1 + h[t];
		tata[nod] = t;
		for (auto i : adia[nod])
			if (i != t)
				g[nod] += calc_g(i, nod);
		return g[nod];
	}
	void calc_id(int nod) {
		int fmax = NMAX - 1;
		id[nod] = cnt++;
		for (auto i : adia[nod])
			if (i != tata[nod] && g[i] > g[fmax])
				fmax = i;
		if (fmax != NMAX - 1)
			link[fmax] = link[nod], calc_id(fmax);
		for (auto i : adia[nod])
			if (i != tata[nod] && i != fmax)
				link[i] = i, calc_id(i);
	}
	vector <Pii> get_intervs(int a, int b) {
		vector <Pii> ans;
		while (link[a] != link[b]) {
			if (h[link[a]] < h[link[b]])
				swap(a, b);
			ans.push_back({ id[link[a]], id[a] });
			a = tata[link[a]];
		}
		/// acum sunt neaparat pe ac lant
		if (h[a] < h[b])
			swap(a, b);
		ans.push_back({ id[b], id[a] });
		return ans;
	}
	void calc() {
		link[1] = 1;
		calc_g(1, 0);
		calc_id(1);
	}
}

namespace Aint {
	const int NMAX = 100010;
	int n, aint[2 * NMAX];

	void update(int poz, int val) {
		poz += n;
		aint[poz] = val;
		while (poz >>= 1)
			aint[poz] = max(aint[2 * poz], aint[2 * poz + 1]);
	}
	int query(int st, int dr) {
		int ans = 0;
		st += n, dr += n + 1;
		while (st != dr) {
			if (st & 1)
				ans = max(ans, aint[st]), st++;
			if (dr & 1)
				dr--, ans = max(ans, aint[dr]);
			st >>= 1, dr >>= 1;
		}
		return ans;
	}
	int query(vector <pair <int, int>> intervs) {
		int ans = 0;
		for (auto i : intervs)
			ans = max(ans, query(i.first, i.second));
		return ans;
	}
}

int v[100010];

int main()
{
	ifstream in("heavypath.in");
	ofstream out("heavypath.out");
	int n, m, a, b;
	in >> n >> m;

	for (int i = 1; i <= n; i++)
		in >> v[i];

	for (int i = 1; i < n; i++) {
		in >> a >> b;
		HP::adia[a].push_back(b);
		HP::adia[b].push_back(a);
	}

	HP::calc();
	Aint::n = n;

	for (int i = 1; i <= n; i++)
		Aint::update(HP::id[i], v[i]);

	while (m--) {
		int t, a, b;
		in >> t >> a >> b;

		if (t == 0)
			Aint::update(HP::id[a], b);
		else
			out << Aint::query(HP::get_intervs(a, b)) << '\n';
	}

	return 0;
}