Cod sursa(job #1699214)

Utilizator al.mocanuAlexandru Mocanu al.mocanu Data 6 mai 2016 17:45:41
Problema Heavy Path Decomposition Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

const int MAX = 100005;
int n, m, t, x, y, z, nrchain;
int v[MAX], h[MAX], size[MAX], ind[MAX], poz[MAX], nodes[MAX], pLant[MAX], arb[MAX];
vector<int> l[MAX], chain[MAX];
bool viz[MAX];

void dfs(int x, int p){
	int best = 0;
	h[x] = h[p] + 1;
	size[x] = 1;

	for(int i = 0; i < l[x].size(); ++i)
		if(l[x][i] != p){
			dfs(l[x][i], x);
			size[x] += size[l[x][i]];
			if(size[best] < size[l[x][i]])
				best = l[x][i];
		}

	for(int i = 0; i < l[x].size(); ++i)
		if(l[x][i] != p && l[x][i] != best)
			pLant[ind[l[x][i]]] = x;

	if(best == 0)
		ind[x] = ++nrchain;
	else
		ind[x] = ind[best];
	chain[ind[x]].push_back(x);
}

void buildArb(){
	for(int i = n; i > 0; --i)
		arb[i] = max(arb[2 * i], arb[2 * i + 1]);
}

void update(int pos, int val){
	arb[pos + n] = val;
	pos += n;
	for(; pos > 1; pos >>= 1)
		arb[pos>>1] = max(arb[pos], arb[pos ^ 1]);
}

int query(int x, int y){
	int res = 0;
	x += n;
	y += n;
	while(x < y){
		if(x & 1)
			res = max(res, arb[x++]);
		if(y & 1)
			res = max(res, arb[--y]);

		x >>= 1;
		y >>= 1;
	}

	return res;
}

int hpd(int x, int y){
	int res = 0;

	while(ind[x] != ind[y]){
		if(h[ind[x]] < h[ind[y]])
			swap(x, y);
		res = max(res, query(poz[x], poz[chain[ind[x]].back()] + 1));
		x = pLant[ind[x]];
	}

	if(poz[x] > poz[y])
		swap(x, y);
	return max(res, query(poz[x], poz[y] + 1));
}

int main(){
	freopen("heavypath.in", "r", stdin);
	freopen("heavypath.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i)
		scanf("%d", &v[i]);
	for(int i = 0; i < n - 1; ++i){
		scanf("%d%d", &x, &y);
		l[x].push_back(y);
		l[y].push_back(x);
	}

	dfs(1, 0);
	int nr = 0;
	for(int i = 1; i <= nrchain; ++i)
		for(int j = 0; j < chain[i].size(); ++j){
			poz[chain[i][j]] = ++nr;
			nodes[nr] = chain[i][j];
			arb[nr + n] = v[chain[i][j]];
		}

	buildArb();

	for(int i = 0; i < m; i++){
		scanf("%d%d%d", &t, &x, &y);
		if(t == 0)
			update(poz[x], y);
		if(t == 1)
			printf("%d\n", hpd(x, y));
	}
	return 0;
}