Cod sursa(job #754481)

Utilizator random.personRandom Person random.person Data 2 iunie 2012 10:48:10
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.77 kb
#include <stdio.h>
#include <algorithm>
#include <vector>
#define NMAX 100005
#define LMAX 400005
#define INF 2000000000
#define pb push_back
using namespace std;
int n,m,val[NMAX],cnt[NMAX],best_n[NMAX],nrc,which[NMAX],poz[NMAX],poz_i[NMAX];
int dec[NMAX],arb[LMAX],ind,dad[NMAX],lvl[NMAX],lst,ldr;
vector <int> A[NMAX],B[NMAX];
bool viz[NMAX];
void read()
{
	scanf("%d%d",&n,&m);
	int i,x,y;
	for (i=1; i<=n; i++)
		scanf("%d",&val[i]);
	for (i=1; i<n; i++)
	{
		scanf("%d%d",&x,&y);
		A[x].pb(y); A[y].pb(x);
	}
}
void dfs(int nod)
{
	viz[nod]=1; cnt[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;
			dfs(vec);
			cnt[nod]+=cnt[vec];
			if (cnt[vec]>cnt[best_n[nod]])
				best_n[nod]=vec;
		}
	}
	if (cnt[nod]==1)
	{
		B[++nrc].pb(nod); which[nod]=nrc;
		return ;
	}
	B[which[best_n[nod]]].pb(nod); which[nod]=which[best_n[nod]];
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i];
		if (lvl[vec]>lvl[nod] && which[nod]!=which[vec])
			dad[which[vec]]=nod;
	}
}
inline int max(int x,int y)
{
	return x>y ? x : y;
}
void cstr(int st,int dr,int nod,int decalaj)
{
	if (st==dr)
	{
		poz_i[B[ind][st-1]]=nod;
		arb[nod+decalaj]=val[B[ind][st-1]];
		return ;
	}
	int mij=(st+dr)/2;
	cstr(st,mij,nod*2,decalaj);
	cstr(mij+1,dr,nod*2+1,decalaj);
	arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
void chains()
{
	dfs(1);
	int i,j;
	for (i=1; i<=nrc; i++)
		reverse(B[i].begin(),B[i].end());
	for (i=1; i<=nrc; i++)
	{
		dec[i]=dec[i-1]+4*B[i].size();
		for (j=0; j<B[i].size(); j++)
			poz[B[i][j]]=j+1;
		ind=i;
		cstr(1,B[i].size(),1,dec[i-1]);
	}
}
void update(int nod,int v,int decalaj)
{
	nod=poz_i[nod];
	arb[nod+decalaj]=v;
	for (nod/=2 ; nod ; nod/=2)
		arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
int find(int st,int dr,int nod,int decalaj)
{
	if (dr<lst || ldr<st)
		return -INF;
	if (lst<=st && dr<=ldr)
		return arb[nod+decalaj];
	int mij=(st+dr)/2;
	return max(find(st,mij,nod*2,decalaj),find(mij+1,dr,nod*2+1,decalaj));
}
void solve()
{
	int i,tip,x,y,z,rez;
	for (i=1; i<=m; i++)
	{
		scanf("%d%d%d",&tip,&x,&y);
		if (tip==0)
			update(x,y,dec[which[x]-1]);
		else
		{
			rez=0;
			while (which[x]!=which[y])
			{
				if (lvl[dad[which[x]]]<lvl[dad[which[y]]])
					z=x,x=y,y=z;
				lst=1; ldr=poz[x];
				rez=max(rez,find(1,B[which[x]].size(),1,dec[which[x]-1]));
				x=dad[which[x]];
			}
			if (lvl[x]>lvl[y])
				z=x,x=y,y=z;
			lst=poz[x]; ldr=poz[y];
			rez=max(rez,find(1,B[which[x]].size(),1,dec[which[x]-1]));
			printf("%d\n",rez);
		}
	}
}
int main()
{
	freopen("heavypath.in","r",stdin);
	freopen("heavypath.out","w",stdout);
	read();
	chains();
	solve();
	return 0;
}