Cod sursa(job #2269794)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 26 octombrie 2018 16:51:59
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
// Я люблую Екатерина
#include <bits/stdc++.h>
using namespace std;

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

const int N = 1e5 + 5;

vector<int> g[N];
int val[N], siz[N], lvl[N], chain[N], peak[N], pos[N], far[N], pom[4 * N];

int n, q, ql, qr, qval, qpos, cptr, eptr;


static int query(int nod, int st, int dr) {
	if (ql <= st && dr <= qr)
		return pom[nod];
	int ant = 0, mid = (st + dr) / 2;
	ant = max(ant, ql <= mid ? query(2 * nod, st, mid) : ant);
	ant = max(ant, mid < qr ? query(2 * nod + 1, mid + 1, dr) : ant);
	return ant; }

static void update(int nod, int st, int dr) {
	if (st == dr) {
		pom[nod] = qval;
		return; }
	int mid = (st + dr) / 2;
	if (qpos <= mid)
		update(2 * nod, st, mid);
	else
		update(2 * nod + 1, mid + 1, dr);
	pom[nod] = max(pom[2 * nod], pom[2 * nod + 1]); }

static void dfs(int u, int pap = 0) {
	lvl[u] = lvl[pap] + 1;
	far[u] = pap;
	siz[u] = 1;
	for (auto v: g[u]) if (v != pap) {
		dfs(v, u);
		siz[u]+= siz[v]; }

	for (int i = 0; i < g[u].size(); ++i)
		if (g[u][i] == pap) {
			swap(g[u][i], g[u].back());
			g[u].pop_back();
			break; } }

static void init(int u) {
	sort(begin(g[u]), end(g[u]), [&](const int &a, const int &b) {
		return siz[a] < siz[b]; });
	for (auto v: g[u])
		init(v);

	chain[u] = g[u].empty() ? ++cptr : chain[g[u].back()];
	peak[chain[u]] = u;
	pos[u] = ++eptr;
	qpos = eptr;
	qval = val[u];
	update(1, 1, n); }

static int heavy_query(int u, int v) {
	int ant = 0;
	while (chain[u] != chain[v]) {
		if (lvl[peak[chain[u]]] < lvl[peak[chain[v]]])
			swap(u, v);
		ql = pos[u];
		qr = pos[peak[chain[u]]];
		ant = max(ant, query(1, 1, n));
		u = far[peak[chain[u]]]; }

	if (lvl[u] < lvl[v])
		swap(u, v);
	ql = pos[u];
	qr = pos[v];
	ant = max(ant, query(1, 1, n));

	return ant; }


int main() {
	fi >> n >> q;
	for (int i = 1; i <= n; ++i)
		fi >> val[i];
	for (int a, b, i = 1; i < n; ++i) {
		fi >> a >> b;
		g[a].push_back(b);
		g[b].push_back(a); }

	dfs(1);
	init(1);

	while (q--) {
		int op;
		fi >> op;

		switch (op) {
		case 1: { // query
			int u, v;
			fi >> u >> v;
			fo << heavy_query(u, v) << '\n';
			break; }

		case 0: { // update
			int p, v;
			fi >> p >> v;
			qpos = pos[p], qval = v;
			update(1, 1, n);
			break; } } }

	return 0; }