Cod sursa(job #1156979)

Utilizator Kira96Denis Mita Kira96 Data 28 martie 2014 10:18:54
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.5 kb
#include<fstream>
#define N 100100
#include<algorithm>
#include<vector>
#define pb push_back
#define FOR(a,b,c) for(int a=b;a<=c;++a)
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
vector<int> A[N],P[N],G[N];
int v[N],poz[N],n,x,y,m,sol,a,tip,b,val,loc,lant[N],paths,niv[N],up[N],subarb[N];
inline void read()
{
	f>>n>>m;
	FOR(i,1,n)
	f>>v[i];
	FOR(i,1,n-1)
	{
		f>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
}
void dfs(int nod,int lvl,int t)
{
	niv[nod]=lvl; subarb[nod]=1;
	FOR(i,0,G[nod].size()-1)
	{
		if(G[nod][i]!=t)
		{
		dfs(G[nod][i],lvl+1,nod);
		up[G[nod][i]]=nod;
		subarb[nod]+=subarb[G[nod][i]];
		}
	}
	if(nod!=1&&G[nod].size()==1)
	{
		lant[nod]=++paths; P[paths].pb(0);
		P[paths].pb(nod); poz[nod]=1;
		return ;
	}
	
	int hv=0;
	FOR(i,0,G[nod].size()-1)
	{
		if(G[nod][i]!=t)
			if(subarb[G[nod][i]]>subarb[hv])
				hv=G[nod][i];
	}
	lant[nod]=lant[hv];
	P[lant[nod]].pb(nod); poz[nod]=P[lant[nod]].size()-1;
}
void init(int ind,int st,int dr,int po)
{
	if(st==dr)
	{
		A[ind][po]=v[P[ind][st]];
		return;
	}
	int mij=(st+dr)>>1;
	init(ind,st,mij,po<<1);
	init(ind,mij+1,dr,(po<<1)+1);
	A[ind][po]=max(A[ind][po<<1],A[ind][(po<<1)+1]);
}
void query(int ind,int st,int dr,int po)
{
	if(st>=a&&dr<=b)
	{
		sol=max(sol,A[ind][po]);
		return;
	}
	int mij=(st+dr)>>1;
	if(a<=mij)
	query(ind,st,mij,po<<1);
	if(b>mij)
	query(ind,mij+1,dr,(po<<1)+1);
}
void update(int ind,int st,int dr,int po)
{
	if(st==dr)
	{
		A[ind][po]=val;
		return;
	}
	int mij=(st+dr)>>1;
	if(loc<=mij)
	update(ind,st,mij,po<<1);
	else
	update(ind,mij+1,dr,(po<<1)+1);
	A[ind][po]=max(A[ind][po<<1],A[ind][(po<<1)+1]);
}
int find(int x,int y)
{
	while(1)
	{
		
		if(lant[x]==lant[y])
		{
			a=min(poz[x],poz[y]); b=max(poz[x],poz[y]);
			query(lant[x],1,P[lant[x]].size()-1,1);
			break;
		}
		
		int t1=P[lant[x]][1];
		int t2=P[lant[y]][1];
		
		if(niv[t1]<niv[t2])
			swap(x,y);
		a=1; b=poz[x]; query(lant[x],1,P[lant[x]].size()-1,1);
		x=up[P[lant[x]][1]];
	}
	return sol;
}
void solve()
{
	dfs(1,1,0);
	FOR(i,1,paths)
	{
		reverse(P[i].begin()+1,P[i].end());
		A[i].resize(4*P[i].size());
		init(i,1,P[i].size()-1,1);
	}
	FOR(i,1,n)
		poz[i]=P[lant[i]].size()-poz[i];
	FOR(i,1,m)
	{
		f>>tip>>a>>b;
		if(!tip)
		{
			val=b,loc=poz[a];
			update(lant[a],1,P[lant[a]].size()-1,1);
		}
		else
		{
			sol=0;
			g<<find(a,b)<<"\n";
		}
	}
}
int main ()
{
	read();
	solve();
	return 0;
}