Cod sursa(job #2206498)

Utilizator Juve45UAIC Alexandru Ionita Juve45 Data 22 mai 2018 19:31:41
Problema Heavy Path Decomposition Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 3.04 kb
#include <bits/stdc++.h>

#define dbg(x) cerr<<#x": "<<x<<"\n"
#define dbg_p(x) //cerr<<#x": "<<x.first<<","<<x.second<<"\n"
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok //cerr<<"OK!\n"

using namespace std;

const int N = 100100;
int n, k, nrl, lvl[N], size[N], a, b, lant[N], first[N], pos[N], q, tata[N], vals[N];
bool use[N];
vector <int> v[N], la[N / 2];

template<class T>
ostream& operator<<(ostream& out, vector<T> v) {
	out << v.size() << '\n';
	for(auto e : v) out << e << ' ';
	return out;
}

class SegmentTree {
public:
	int * v, n;
	
	SegmentTree() {
	}

	int que(int node, int l, int r, int x, int y) {
		if(x <= l && r <= y)
			return v[node];

		if(r < x || l > y)
			return 0;
		
		int mid = (l + r) / 2;
		return max(que(2 * node, l, mid, x, y), que(2 * node + 1, mid + 1, r, x, y));
	}

	void upd(int node, int l, int r, int pos, int val) {
		if(l == r)
			v[node] = val;
		else {
			int mid = (l + r) / 2;
			if(pos <= mid) upd(2 * node, l, mid, pos, val);
			else upd(2 * node + 1, mid + 1, r, pos, val);
			v[node] = max(v[node * 2], v[2 * node + 1]);
		}
	}

	void update(int pos, int val) {
		upd(1, 0, n, pos, val);
	}

	int query(int a, int b) {
		return que(1, 0, n, a, b);
	}

}st[100100];

void dfs1(int k, int lv, int t) {
	tata[k] = t;
	use[k] = 1;
	size[k] = 1;
	lvl[k] = lv;
	
	for(auto i : v[k]) {
		if(use[i]) continue; 
		dfs1(i, lv + 1, k);
		size[k] += size[i];
	}
}


void dfs2(int k, int lant_k) {
	use[k] = 1;
	lant[k] = lant_k;
	pos[k] = la[lant_k].size();
	la[lant_k].push_back(k);

	if(!first[lant_k]) 
		first[lant_k] = k;
	
	int szmax = 0, index = -1;

	for(auto i : v[k])
		if(!use[i] && size[i] > szmax) {
			szmax = size[i];
			index = i;
		}
		
	for(auto i : v[k]) {
		if(use[i]) continue;
		if(i == index) dfs2(i, lant_k);
		else dfs2(i, nrl++);
	}

}

int solve(int a, int b) {
	if(a == -1) a = 1;
	if(lant[a] == lant[b])
		return st[lant[a]].query(min(pos[a], pos[b]), max(pos[b], pos[a]));
	if(lvl[first[lant[a]]] < lvl[first[lant[b]]]) swap(a, b);

	return max(st[lant[a]].query(0, pos[a]), solve(tata[first[lant[a]]], b));
}



int main() {
	
	ifstream cin("heavypath.in");
	ofstream cout("heavypath.out");	
	// freopen("heavypath.in", "r", stdin);
	// freopen("heavypath.out", "w", stdout);

	ios_base::sync_with_stdio(false);
	cin >> n >> q;

	for(int i = 1; i <= n; i++)
		cin >> vals[i];

	for(int i = 1; i < n; i++) {
		cin >> a >> b;
		v[a].push_back(b);
		v[b].push_back(a);

	}

	dfs1(1, 1, -1);
	memset(use, 0, sizeof use);
	dfs2(1, nrl++);
	
	for(int i = 0; i < nrl; i++){
		st[i].v = new int[4 * la[i].size() + 60];
		memset(st[i].v, 0, (4 * la[i].size() + 60) * sizeof(int));
		st[i].n = la[i].size();
	}

	// dbg_v(vals, n + 1);
	// dbg_v(lant, n + 1);
	// dbg_v(pos, n + 1);
	for(int i = 1; i <= n; i++)
		st[lant[i]].update(pos[i], vals[i]);
	// cin >> q;
	int op;
	for(int i = 1; i <= q; i++) {
		cin >> op >> a >> b;
		// dbg(a);
		// dbg(b);
			// dbg_ok;
		if(op == 0)
			st[lant[a]].update(pos[a], b);
		else {
			int ans = 0;
			cout << solve(a, b) << '\n';
		}
	}

}