Cod sursa(job #633796)

Utilizator cosmin79Carabet Cosmin Andrei cosmin79 Data 14 noiembrie 2011 20:49:57
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.56 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#define NMAX 100005
#define LMAX (1<<18)
#define pb push_back
using namespace std;
int n,m,r,val[NMAX],nr[NMAX],fii[NMAX],dad[NMAX],lvl[NMAX],L[NMAX],which[NMAX],best[NMAX],nl,poz[NMAX],C[NMAX],D[NMAX],arb[LMAX],rez;
vector <int> A[NMAX],B[NMAX];
char viz[NMAX];
void read()
{
	scanf("%d%d",&n,&m);
	int i,a,b;
	for (i=1; i<=n; i++)
		scanf("%d",&val[i]);
	for (i=1; i<n; i++)
	{
		scanf("%d%d",&a,&b);
		A[a].pb(b);
		A[b].pb(a);
	}
}
void dfs(int nod)
{
	viz[nod]=1;
	nr[nod]=1;
	int i,vec;
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i];
		if (!viz[vec])
		{
			lvl[vec]=lvl[nod]+1;
			fii[nod]++;
			dfs(vec);
			nr[nod]+=nr[vec];
			if (nr[vec]>nr[best[nod]])
				best[nod]=vec;
		}
	}
	if (!fii[nod])
	{
		nl++;
		L[nl]=1; which[nod]=nl;
		B[nl].pb(nod);
		return ;
	}
	L[which[best[nod]]]++;
	B[which[best[nod]]].pb(nod);
	which[nod]=which[best[nod]];
	
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i];
		if (vec!=best[nod] && fii[vec]<fii[nod])
			dad[which[vec]]=nod;
	}
}
void chains()
{
	dfs(1);
	int i,j,nod;
	for (i=1; i<=nl; i++)
		reverse(B[i].begin(),B[i].end());
	for (i=1; i<=nl; i++)
	{
		if (i>1)
			D[i]=D[i-1]+B[i-1].size();
		else
			D[i]=1;
		for (j=0; j<B[i].size(); j++)
		{
			nod=B[i][j];
			C[++r]=nod;
			poz[nod]=r;
		}
	}
}
inline int max(int x,int y)
{
	return x>y ? x : y;
}
void update(int st,int dr,int nod,int position,int value)
{
	if (st==dr)
	{
		arb[nod]=value;
		return ;
	}
	int mij=(st+dr)/2;
	if (position<=mij)
		update(st,mij,nod*2,position,value);
	else
		update(mij+1,dr,nod*2+1,position,value);
	arb[nod]=max(arb[nod*2],arb[nod*2+1]);
}
int query(int st,int dr,int nod,int a,int b)
{
	if (b<st || a>dr)
		return 0;
	if (a<=st && dr<=b)
		return arb[nod];
	int mij=(st+dr)/2;
	return max(query(st,mij,nod*2,a,b),query(mij+1,dr,nod*2+1,a,b));
}
void solve()
{
	int i,tip,x,y;
	for (i=1; i<=n; i++)
		update(1,n,1,poz[i],val[i]);
	for (i=1; i<=m; i++)
	{
		scanf("%d%d%d",&tip,&x,&y);
		if (tip==0)
			update(1,n,1,poz[x],y);
		else
		{
			rez=0;
			while (which[x]!=which[y])
			{
				if (lvl[dad[which[x]]]<lvl[dad[which[y]]])
					swap(x,y);
				rez=max(rez,query(1,n,1,D[which[x]],poz[x]));
				x=dad[which[x]];
			}
			if (poz[x]>poz[y])
				swap(x,y);
			rez=max(rez,query(1,n,1,poz[x],poz[y]));
			printf("%d\n",rez);
		}
	}
}
int main()
{
	freopen("heavypath.in","r",stdin);
	freopen("heavypath.out","w",stdout);
	read();
	chains();
	solve();
	return 0;
}