Cod sursa(job #967682)

Utilizator ahmed.abdraboahmed.abdrabo ahmed.abdrabo Data 28 iunie 2013 11:48:03
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

const int H = 17;
const int MAX = 1 << H;
int M, N, a, b, t, x, y;
bool heavy[MAX];
int chain[MAX], depth[MAX], parent[MAX], pos[MAX], size[MAX], sorted[MAX], ST[MAX + MAX], V[MAX];
vector<int> chains[MAX];
vector<int> G[MAX];

bool cmp(int a, int b) {
	return depth[a] < depth[b];
}

void dfs(int u, int d = 0) {
	chain[u] = u;
	depth[u] = d;
	size[u] = 1;
	for (size_t i = 0; i < G[u].size(); i++) {
		int v = G[u][i];
		if (size[v] == 0) {
			dfs(v, d + 1);
			parent[v] = u;
			size[u] += size[v];
		}
	}
	for (size_t i = 0; i < G[u].size(); i++) {
		int v = G[u][i];
		if (parent[v] == u && 2 * size[v] >= size[u])
			heavy[v] = true;
	}
}

void hld(int u) {
	chain[u] = heavy[u] ? chain[parent[u]] : u;
	for (size_t i = 0; i < G[u].size(); i++) {
		int v = G[u][i];
		if (parent[v] == u)
			hld(v);
	}
}

int lca(int a, int b) {
	while (chain[a] != chain[b])
		if (depth[chain[a]] < depth[chain[b]])
			b = parent[chain[b]];
		else
			a = parent[chain[a]];
	return depth[a] < depth[b] ? a : b;
}

void set(int index, int value) {
	ST[index += MAX] = value;
	while (index > 1) {
		index >>= 1;
		ST[index] = max(ST[index << 1], ST[index << 1 | 1]);
	}
}

int get(int a, int b, int root = 1, int left = 0, int right = MAX) {
	if (left == a && b == right)
		return ST[root];
	int mid = (left + right) >> 1;
	if (b <= mid)
		return get(a, b, root << 1, left, mid);
	if (mid <= a)
		return get(a, b, root << 1 | 1, mid, right);
	return max(get(a, mid, root << 1, left, mid), get(mid, b, root << 1 | 1, mid, right));
}

int query(int x, int y) {
	int ans = V[x];
	while (x != y) {
		if (chain[x] == chain[y]) {
			ans = max(ans, get(pos[x], pos[y] + 1));
			y = x;
		} else {
			ans = max(ans, get(pos[chain[y]], pos[y] + 1));
			y = parent[chain[y]];
		}
	}
	return ans;
}

int main() {
	scanf("%d%d", &N, &M);
	for (int i = 1; i <= N; i++)
		scanf("%d", V + i);
	for (int i = 2; i <= N; i++) {
		scanf("%d%d", &a, &b);
		G[a].push_back(b);
		G[b].push_back(a);
	}
	dfs(1);
	hld(1);
	for (int i = 1; i <= N; i++)
		sorted[i] = i;
	sort(sorted + 1, sorted + 1 + N, cmp);
	for (int i = 1; i <= N; i++)
		chains[chain[sorted[i]]].push_back(sorted[i]);
	for (int i = 1, c = 0; i <= N; i++) {
		for (size_t j = 0; j < chains[i].size(); j++) {
			pos[chains[i][j]] = c++;
			ST[pos[chains[i][j]] + MAX] = V[chains[i][j]];
		}
	}
	for (int i = MAX - 1; i > 0; i--)
		ST[i] = max(ST[i << 1], ST[i << 1 | 1]);
	for (int i = 1; i <= M; i++) {
		scanf("%d%d%d", &t, &x, &y);
		if (t == 0) {
			V[x] = y;
			set(pos[x], y);
		}
		if (t == 1) {
			int p = lca(x, y);
			printf("%d\n", max(query(p, x), query(p, y)));
		}
	}
	return 0;
}