Cod sursa(job #1219653)

Utilizator vladrochianVlad Rochian vladrochian Data 14 august 2014 18:58:17
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 kb
#include <fstream>
#include <vector>
#define LS nod<<1
#define RS (nod<<1)+1
#define MID ((l+r)>>1)
#define GR(x,y) GetRange(x,y,1,1,n)
using namespace std;
int n,m,val[100005],aint[400005],level[100005],weight[100005],lant[100005],tt[100005],nl,pos[100005],vpos,aibase[100005];
bool viz[100005];
vector<int> g[100005],chain[100005];
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
void dfs(int nod)
{
	viz[nod]=1;
	weight[nod]=1;
	int maxw=0;
	for(size_t i=0;i<g[nod].size();++i)
	{
		int vecin=g[nod][i];
		if(viz[vecin])
			continue;
		tt[vecin]=nod;
		level[vecin]=level[nod]+1;
		dfs(vecin);
		if(weight[vecin]>weight[maxw])
			maxw=vecin;
		weight[nod]+=weight[vecin];
	}
	if(maxw)
		lant[nod]=lant[maxw];
	else
		lant[nod]=++nl;
	chain[lant[nod]].push_back(nod);
}
void Build(int nod,int l,int r)
{
	if(l==r)
	{
		aint[nod]=val[aibase[l]];
		return;
	}
	Build(LS,l,MID);
	Build(RS,MID+1,r);
	aint[nod]=max(aint[LS],aint[RS]);
}
void Update(int x,int val,int nod,int l,int r)
{
	if(l==r)
	{
		aint[nod]=val;
		return;
	}
	if(x>MID)
		Update(x,val,RS,MID+1,r);
	else
		Update(x,val,LS,l,MID);
	aint[nod]=max(aint[LS],aint[RS]);
}
inline int TataLant(int x)
{
	return tt[chain[x].back()];
}
int GetRange(int x,int y,int nod,int l,int r)
{
	if(r<x || l>y)
		return 0;
	if(l>=x && r<=y)
		return aint[nod];
	return max(GetRange(x,y,LS,l,MID),GetRange(x,y,RS,MID+1,r));
}
int Query(int x,int y)
{
	int vmx=0;
	while(lant[x]!=lant[y])
	{
		int ttx=TataLant(lant[x]),tty=TataLant(lant[y]);
		if(level[ttx]>level[tty])
		{
			vmx=max(vmx,GR(pos[x],pos[chain[lant[x]].back()]));
			x=ttx;
		}
		else
		{
			vmx=max(vmx,GR(pos[y],pos[chain[lant[y]].back()]));
			y=tty;
		}
	}
	if(pos[x]>pos[y])
		swap(x,y);
	return max(vmx,GR(pos[x],pos[y]));
}
int main()
{
	int i,x,y;
	fin>>n>>m;
	for(i=1;i<=n;++i)
		fin>>val[i];
	for(i=1;i<n;++i)
	{
		fin>>x>>y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	level[1]=1;
	dfs(1);
	for(i=1;i<=nl;++i)
		for(size_t j=0;j<chain[i].size();++j)
			aibase[pos[chain[i][j]]=++vpos]=chain[i][j];
	Build(1,1,n);
	while(m--)
	{
		fin>>i>>x>>y;
		if(i)
			fout<<Query(x,y)<<"\n";
		else
			Update(pos[x],y,1,1,n);
	}
	return 0;
}