Cod sursa(job #794073)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 5 octombrie 2012 15:17:03
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.05 kb
#include<fstream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,nrlant;
vector <int> G[100100];
bool viz[100100];
int val[100100],weight[100100];
int lant[100100],dim[100100],lanttata[100100];
vector <int> L[100100];
int Aint[500000],start[100100],sol,poz[100100];
int niv[100100],nivlant[100100],poznod[100100];

inline void DFS(int x,int tata)
{
	viz[x]=true;
	weight[x]=1;
	vector <int>::iterator it;
	bool frunza=true;
	int heavynod=0;
	for(it=G[x].begin();it!=G[x].end();it++)
	{
		if(!viz[*it])
		{
			frunza=false;
			niv[*it]=niv[x]+1;
			DFS(*it,x);
			weight[x]+=weight[*it];
			if(!heavynod || weight[heavynod]<weight[*it])
				heavynod=*it;
		}
	}
	if(frunza)
	{
		lant[x]=++nrlant;
		dim[nrlant]=1;
		L[nrlant].push_back(x);
		poz[x]=0;
	}
	else
	{
		lant[x]=lant[heavynod];
		dim[lant[x]]++;
		L[lant[x]].push_back(x);
		poz[x]=L[lant[x]].size()-1;
		for(it=G[x].begin();it!=G[x].end();it++)
		{
			if(*it==heavynod || *it==tata)
				continue;
			lanttata[lant[*it]]=x;
			nivlant[lant[*it]]=niv[x];
		}
	}
	
}

inline void Build(int nod,int st,int dr,int delay,int lant)
{
	if(st==dr)
	{
		Aint[nod+delay]=val[L[lant][st-1]];
		return;
	}
	int mij=(st+dr)/2;
	Build(2*nod,st,mij,delay,lant);
	Build(2*nod+1,mij+1,dr,delay,lant);
	Aint[nod+delay]=max(Aint[2*nod+delay],Aint[2*nod+1+delay]);
}

inline void Update(int nod,int st,int dr,int delay,int poz,int v)
{
	if(st==dr)
	{
		Aint[nod+delay]=v;
		return;
	}
	int mij=(st+dr)/2;
	if(poz<=mij)
		Update(2*nod,st,mij,delay,poz,v);
	else
		Update(2*nod+1,mij+1,dr,delay,poz,v);
	Aint[nod+delay]=max(Aint[2*nod+delay],Aint[2*nod+1+delay]);
}

inline void Query(int nod,int st,int dr,int delay,int a,int b)
{
	if(a<=st && dr<=b)
	{
		sol=max(sol,Aint[nod+delay]);
		return;
	}
	int mij=(st+dr)/2;
	if(a<=mij)
		Query(2*nod,st,mij,delay,a,b);
	if(mij+1<=b)
		Query(2*nod+1,mij+1,dr,delay,a,b);
}

inline void DescompunereLanturi()
{
	niv[1]=1;
	DFS(1,0);
	int i,j;
	vector <int>::iterator it;
	for(i=1;i<=nrlant;i++)
	{
		reverse(L[i].begin(),L[i].end());
		for(it=L[i].begin(),j=1;it!=L[i].end();it++,j++)
			poznod[*it]=j;
		if(i>1)
			start[i]=start[i-1]+4*dim[i-1];
		Build(1,1,dim[i],start[i],i);
	}
}

int main()
{
	int i,x,y,op;
	ifstream fin("heavypath.in");
	ofstream fout("heavypath.out");
	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);
	}
	
	DescompunereLanturi();
	
	for(i=1;i<=m;i++)
	{
		fin>>op>>x>>y;
		if(op==0)
			Update(1,1,dim[lant[x]],start[lant[x]],poznod[x],y);
		else
		{
			sol=0;
			while(1)
			{
				if(lant[x]==lant[y])
				{
					if(niv[x]>niv[y])
						swap(x,y);
					Query(1,1,dim[lant[x]],start[lant[x]],poznod[x],poznod[y]);
					break;
				}
				if(nivlant[lant[x]]<nivlant[lant[y]])
					swap(x,y);
				Query(1,1,dim[lant[x]],start[lant[x]],1,poznod[x]);
				x=lanttata[lant[x]];
			}
			fout<<sol<<"\n";
		}
	}
	fin.close();
	fout.close();
	return 0;
}