Cod sursa(job #2206470)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 22 mai 2018 19:03:11
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include <bits/stdc++.h>
#define Nmax 100002
using namespace std;
 
ifstream f("heavypath.in");
ofstream g("heavypath.out");

vector<int> v[Nmax];
int x, y, N, M, val[Nmax], sz[Nmax], H[Nmax], niv[Nmax], ID[Nmax], sav[Nmax], t, a, b, pos[Nmax], T[Nmax];
vector<vector<int> > L, Aint;
int lg[Nmax];

void dfs(int nod, int ant, int nv){
	int mx = 0;
	sz[nod] = 1;
	niv[nod] = nv;
	T[nod] = ant;

	if (v[nod].size() == 1){
		ID[nod] = L.size();
		L.push_back(vector<int>());
		L[ID[nod]].push_back(nod);
		pos[nod] = 0;
		return;
	}

	for (auto it : v[nod]){
		if (it==ant) continue;
		dfs(it, nod, nv + 1);
		sz[nod] += sz[it];
		if (sz[it] > mx) sav[nod] = it;
	}

	L[ID[sav[nod]]].push_back(nod);
	ID[nod] = ID[sav[nod]];
	pos[nod] = L[ID[nod]].size() - 1;
}

void get_H(int nod,int ant){
	if (H[nod] == 0) H[nod] = nod;
	H[sav[nod]] = H[nod];
	for (auto it : v[nod]){
		if (it == ant) continue;
		get_H(it, nod);
	}
}

void build(int index){
	Aint.push_back(vector<int>());
	lg[index] = 1;
	while (lg[index] < L.size()) lg[index]*=2;
	lg[index]*=2;
	Aint[index].resize(lg[index]+1);

	for (int i=lg[index];i<=lg[index]+L[index].size()-1;i++){
		Aint[index][i] = val[L[index][i - lg[index]]];
	}

	for (int i=lg[index]-1;i>=1;i--){
		Aint[index][i] = max(Aint[index][i*2],Aint[index][i*2+1]);
	}
}

void change(int index, int pos, int val){
	Aint[index][pos + lg[index] - 1] = val;
	pos+=lg[index]-1;
	pos/=2;
	for (;pos>=1;pos>>=1){
		Aint[index][pos] = max(Aint[index][pos*2],Aint[index][pos*2+1]);
	}
}

int query(int index, int st, int dr){
	int ans = 0;
	st += lg[index] - 1;
	dr += lg[index];
	for (;st!=dr;st<<=1,dr<<=1){
		if (st&1)    ans = max(ans,Aint[index][st++]);
		if (!(dr&1)) ans = max(ans,Aint[index][--dr]); 
	}
	return ans;
}

int solve(int a,int b){
	if (niv[H[a]] < niv[H[b]]) swap(a,b);
	if (ID[a]==ID[b]){
		if (pos[a]>pos[b]) swap(a,b);
		return query(ID[a],a,b);
	}

	return query(ID[a],a,H[a]) + solve(T[H[a]],b);
}


int main(){
	f >> N >> M;
	
	for (int i=1;i<=N;i++){
		f >> val[i];
	}

	for (int i=1;i<N;i++){
		f >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}

	dfs(1, -1, 0);
	get_H(1, -1);


	for (int i=0;i<L.size();i++){
		build(i);
	}

	for (int i=1;i<=M;i++){
		f >> t >> a >> b;
		if (t == 0){
			change(ID[a],pos[a],b);
		}
		else{
			g << solve(a,b) << '\n';
		}
	}

	return 0;
}