Cod sursa(job #2660668)

Utilizator BogdanTicuTicu Bogdan Valeriu BogdanTicu Data 20 octombrie 2020 01:40:59
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("heavypath.in");
ofstream out("heavypath.out");

int val[100005],sizee[100005],level[100005];
int tata[100005],lant[100005],poz[100005],varf[100005];
int arb[400005];
int nrlant,pos,qpos,qval,start,finish,n,m;
vector<int> graf[100005];
bool ok(int a,int b)
{
	return sizee[a]<sizee[b];
}


void dfs(int nod,int a)
{
	sizee[nod]=1;
	for(auto x:graf[nod])
	{
		if(x!=a)
		{
			tata[x]=nod;
			level[x]=level[nod]+1;
			dfs(x,nod);
			sizee[nod]+=sizee[x];
		}
	}
	for(int i=0;i<graf[nod].size();i++)
		if(graf[nod][i]==a)
		{
			swap(graf[nod][i],graf[nod].back());
			graf[nod].pop_back();
		}
}


void update(int nod,int st,int dr)
{
	if(st==dr)
	{
		arb[nod]=qval;
		return;
	}
	int mid=(st+dr)/2;
	if(qpos<=mid)
		update(2*nod,st,mid);
	else
		update(2*nod+1,mid+1,dr);
	arb[nod]=max(arb[2*nod],arb[2*nod+1]);
}

int query(int nod,int st,int dr)
{
	if(start<=st && dr<=finish)
		return arb[nod];
	int mid=(st+dr)/2;
	int ans=0;
	if(start<=mid)
		ans=max(ans,query(2*nod,st,mid));
	if(mid<finish)
		ans=max(ans,query(2*nod+1,mid+1,dr));
	return ans;
}


int QUERY(int x,int y)
{
	int ans=0;
	while(lant[x]!=lant[y])
	{
		if(level[varf[lant[x]]] < level[varf[lant[y]]])
			swap(x,y);
		start=poz[x];	
		finish=poz[varf[lant[x]]];
		ans=max(ans,query(1,1,n));
		x=tata[varf[lant[x]]];
	}
	if(level[x]<level[y])
		swap(x,y);
	start=poz[x];	
	finish=poz[y];
	ans=max(ans,query(1,1,n));
	return ans;
}


void descompunere(int nod)
{
	sort(graf[nod].begin(),graf[nod].end(),ok);
	for(auto x:graf[nod])
	{
		descompunere(x);
	}
	lant[nod]=(graf[nod].empty() ? ++nrlant : lant[graf[nod].back()]);
	varf[lant[nod]]=nod;
	poz[nod] = ++pos;
	qpos=poz[nod];
	qval=val[nod];
	update(1,1,n);

}
int main()
{
	in>>n>>m;
	for(int i=1;i<=n;i++)
		in>>val[i];
	for(int i=1;i<n;i++)
	{
		int x,y;
		in>>x>>y;
		graf[x].push_back(y);
		graf[y].push_back(x);
	}
	tata[1]=1;
	level[1]=1;
	dfs(1,0);
	descompunere(1);
	for(int i=1;i<=m;i++)
	{
		int cod,x,y;
		in>>cod>>x>>y;
		if(cod==0)
		{
			qpos=poz[x];
			qval=y;
			update(1,1,n);
		}
		else
			out<<QUERY(x,y)<<"\n";
	}
	return 0;
}