Cod sursa(job #2416952)

Utilizator shantih1Alex S Hill shantih1 Data 28 aprilie 2019 17:26:38
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.11 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int nmx=100005;
int n,i,j,nr,m,np,x,y,op,k,sol,mx,pu,val,a,b,ex,rez;
int ct[nmx],v[nmx],tt[nmx],pth[nmx],pos[nmx],ext[nmx],he[nmx],ai[4*nmx],st[nmx];

vector<int> ad[nmx];

void dfs_cate(int n)
{
	ct[n]=1;
	for(int i:ad[n])
		if(!ct[i])
		{
			dfs_cate(i);
			ct[n]+=ct[i];
		}
}
void make_paths(int n,int t,int h,int nw)
{
	st[++ex]=n;
	if(nw) {
		np++;
		pos[n]=1;
		pth[n]=np;
		ext[n]=ex-1;
		tt[n]=t;
		he[n]=h-1;
	}
	else {
		pos[n]=pos[t]+1;
		pth[n]=pth[t];
		ext[n]=ext[t];
		he[n]=he[t];
		tt[n]=tt[t];
	}
	if(ad[n].size()==1 && n!=1)
		return;
	
	int ki=0;
	for(int i:ad[n])
		if(ct[i]<ct[n] && ct[i]>ct[ki])
			ki=i;
	
	make_paths(ki, n, h+1, 0);
	for(int i:ad[n])
		if(ct[i]<ct[n] && i!=ki)
			make_paths(i, n, h+1, 1);
}
void build(int n,int l,int r)
{
	if(l==r)
	{
		ai[n]=v[st[++k]];
		return;
	}
	int m=(l+r)/2;
	build(2*n,l,m);
	build(2*n+1,m+1,r);
	ai[n]=max(ai[2*n],ai[2*n+1]);
}
void true_query(int n,int l,int r)
{
	if(a<=l && r<=b)
	{
		rez=max(rez, ai[n]);
		return;
	}
	int m=(l+r)/2;
	if(a<=m)	true_query(2*n,l,m);
	if(b>m)		true_query(2*n+1,m+1,r);
}
int query(int a,int b)
{
	rez=0;
	::a=a;
	::b=b;
	true_query(1,1,n);
	return rez;
}
void true_update(int n,int l,int r)
{
	if(l==r)
	{
		ai[n]=b;
		return;
	}
	int m=(l+r)/2;
	if(a<=m)	true_update(2*n,l,m);
	else		true_update(2*n+1,m+1,r);
	ai[n]=max(ai[2*n],ai[2*n+1]);
}
void update(int pos,int val)
{
	a=pos;
	b=val;
	true_update(1,1,n);
}

int main() {
		
	fin>>n>>m;
	for(i=1;i<=n;i++)
		fin>>v[i];
	for(i=1;i<n;i++)
	{
		fin>>x>>y;
		ad[x].push_back(y);
		ad[y].push_back(x);
	}
	
	dfs_cate(1);
	make_paths(1,0,1,1);
	
	k=0;
	build(1,1,n);
	
	while(m--)
	{
		fin>>op>>x>>y;
		
		if(op==0)
			update(ext[x]+pos[x], y);
		else
		{
			sol=0;
			while(1)
			{
				if(pth[x]==pth[y])
				{
					sol=max(sol, query(ext[x]+min(pos[x],pos[y]), ext[x]+max(pos[x],pos[y])));
					break;
				}
				
				if(he[x]<he[y])	k=x, x=y, y=k;
				
				sol=max(sol, query(ext[x]+1,ext[x]+pos[x]));
				
				x=tt[x];
			}
			fout<<sol<<"\n";
		}
	}
}