Cod sursa(job #2206501)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 22 mai 2018 19:33:08
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.37 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 && ant != -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;
            mx = sz[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[index].size()) lg[index]*=2;
	Aint[index].resize(lg[index]*4+10);

	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){
    pos++;
	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){
	st++;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],pos[a],pos[b]);
	}

	return max(query(ID[a],pos[a],pos[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;
}