Cod sursa(job #3259405)

Utilizator vladdobro07vladdd vladdobro07 Data 26 noiembrie 2024 11:20:46
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.69 kb
#include <bits/stdc++.h>

#define OP_UPDATE 0
#define OP_QUERY 1

using namespace std;

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

const int NMAX = 1e5;

struct AINT {
	struct node {
		int maxx = 0;
	};

	vector<node>aint;

	AINT() {
		aint.resize(4 * NMAX + 3);
	}

	void update(int nod, int st, int dr, int l, int r, int val) {
		if(l > dr || r < st || dr < st || r < l)
			return;

		if(st == l && dr == r) {
			aint[nod].maxx = val;
		} else {
			int mid = (st + dr) / 2;

			update(nod * 2, st, mid, l, min(mid, r), val);
			update(nod * 2 + 1, mid + 1, dr, max(mid + 1, l), r, val);

			aint[nod].maxx = max(aint[nod * 2].maxx, aint[nod * 2 + 1].maxx);
		}
	}

	int query(int nod, int st, int dr, int l, int r) {
		if(l > dr || r < st || dr < st || r < l)
			return 0;

		if(st == l && dr == r) {
			return aint[nod].maxx;
		} else {
			int mid = (st + dr) / 2;

			return max(query(nod * 2, st, mid, l, min(mid, r)), query(nod * 2 + 1, mid + 1, dr, max(mid + 1, l), r));
		}
	}
};

AINT aint;

struct Node {
	int val = 0, parent = 0, lvl = 0, heavy = 0, head = 0, poz = 0;
};

vector<vector<int>> edge;

int t, n, q, x, y;

struct heavyLightDecomp {
	vector<int> decomp;
	int curpoz = 0;

	int dfsCalc(int nod, int tata, vector<Node>& nodes) {
		int dsize = 1, maxChild = 0;
		Node& curNode = nodes[nod];

		curNode.parent = tata;
		curNode.lvl = nodes[tata].lvl + 1;

		for(int child : edge[nod]) {
			if(child == tata)
				continue;

			int childSize = dfsCalc(child, nod, nodes);

			if(childSize > maxChild) {
				maxChild = childSize;
				curNode.heavy = child;
			}

			dsize += childSize;
		}
		return dsize;
	}

	void dfsDecomp(int nod, int head, vector<Node>& nodes) {
		Node& curNode = nodes[nod];

		curNode.head = head;
		curNode.poz = ++curpoz;
		decomp.push_back(nod);

		if(curNode.heavy != 0)
			dfsDecomp(curNode.heavy, head, nodes);

		for(int child : edge[nod]) {
			if(child == curNode.heavy || child == curNode.parent)
				continue;

			dfsDecomp(child, child, nodes);
		}
	}

	void dfs(int nod, vector<Node>& nodes, int tata = 0) {
		fout << nod << " parent: " << nodes[nod].parent << " lvl: " << nodes[nod].lvl << " head: " << nodes[nod].head << " heavy: " << nodes[nod].heavy << " poz: " << nodes[nod].poz << "\n";
		for(int child : edge[nod]) {
			if(child == tata)
				continue;

			dfs(child, nodes, nod);
		}
	}
};

heavyLightDecomp heavylight;

vector<Node> nodes;

int query(int x, int y) {
	int ans = 0;

	while(nodes[x].head != nodes[y].head) {
		if(nodes[nodes[x].head].lvl > nodes[nodes[y].head].lvl)
			swap(x, y);

		ans = max(ans, aint.query(1, 1, n, nodes[nodes[y].head].poz, nodes[y].poz));
		y = nodes[nodes[y].head].parent;
	}

	if(nodes[x].lvl > nodes[y].lvl)
		swap(x, y);

	ans = max(ans, aint.query(1,1,n,nodes[x].lvl, nodes[y].lvl));

	return ans;
}

void solve() {
	heavylight.dfsCalc(1, 0, nodes);
	heavylight.dfsDecomp(1, 1, nodes);
//	heavylight.dfs(1, nodes);

	for(int i = 1; i <= n; i++)
		aint.update(1, 1, n, i, i, nodes[i].val);

	for(int i = 1; i <= q; i++) {
		fin >> t >> x >> y;

		if(t == OP_UPDATE)
			aint.update(1, 1, n, nodes[x].poz, nodes[x].poz, y);
		else if(t == OP_QUERY)
			fout << query(x, y) << "\n";
	}
}

void read() {
	fin >> n >> q;

	edge.resize(n + 1);
	nodes.resize(n + 1);
	heavylight.decomp.resize(n + 1);

	for(int i = 1; i <= n; i++)
		fin >> nodes[i].val;

	for(int i = 1; i <= n - 1; i++) {
		fin >> x >> y;

		edge[x].push_back(y);
		edge[y].push_back(x);
	}
}

int main() {
//        iostream::sync_with_stdio(false);
//        fin.tie(NULL);

	read();
	solve();
	return 0;
}