Cod sursa(job #797647)

Utilizator radustn92Radu Stancu radustn92 Data 14 octombrie 2012 16:05:23
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.95 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#define NMAX 100005
#define HMAX 400005
#define pb push_back
using namespace std;
int n,m,V[NMAX],B[NMAX],best[NMAX],nr_chains,which[NMAX],where[NMAX],arb[HMAX],dad[NMAX];
int lvl[NMAX],dec[NMAX],father[NMAX],v1,v2,p1,p2,rez;
vector <int> A[NMAX],C[NMAX];
bool viz[NMAX];
void read()
{
	scanf("%d%d",&n,&m);
	int i,x,y;
	for (i=1; i<=n; i++)
		scanf("%d",&V[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; B[nod]=1;
	int i,vec;
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i];
		if (!viz[vec])
		{
			father[vec]=nod; lvl[vec]=lvl[nod]+1;
			dfs(vec);
			B[nod]+=B[vec];
			if (B[vec]>B[best[nod]])
				best[nod]=vec;
		}
	}
	if (B[nod]==1)
	{
		nr_chains++; which[nod]=nr_chains;
		C[nr_chains].pb(nod);
		return ;
	}
	C[which[best[nod]]].pb(nod); which[nod]=which[best[nod]];
	
	for (i=0; i<A[nod].size(); i++)
	{
		vec=A[nod][i];
		if (father[vec]==nod && vec!=best[nod])
			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,int ind)
{
	if (st==dr)
	{
		arb[nod+decalaj]=V[C[ind][st-1]];
		return ;
	}
	int mij=(st+dr)/2;
	cstr(st,mij,nod*2,decalaj,ind);
	cstr(mij+1,dr,nod*2+1,decalaj,ind);
	arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
void cons()
{
	int i,j;
	for (i=1; i<=nr_chains; i++)
		reverse(C[i].begin(),C[i].end());
	for (i=1; i<=nr_chains; i++)
	{
		for (j=0; j<C[i].size(); j++)
			where[C[i][j]]=j+1;
		
		dec[i]=dec[i-1]+4*C[i].size();
		cstr(1,C[i].size(),1,dec[i-1],i);
	}
}
void update(int st,int dr,int nod,int decalaj)
{
	if (st==dr)
	{
		arb[nod+decalaj]=v2;
		return ;
	}
	int mij=(st+dr)/2;
	if (where[v1]<=mij)
		update(st,mij,nod*2,decalaj);
	else
		update(mij+1,dr,nod*2+1,decalaj);
	
	arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
int search(int st,int dr,int nod,int decalaj)
{
	if (p1<=st && dr<=p2)
		return arb[nod+decalaj];
	if (p2<st || dr<p1)
		return 0;
	int mij=(st+dr)/2;
	return max(search(st,mij,nod*2,decalaj),search(mij+1,dr,nod*2+1,decalaj));
}
void solve()
{
	int i,tip;
	lvl[0]=-1;
	for (i=1; i<=m; i++)
	{
		scanf("%d%d%d",&tip,&v1,&v2);
		if (tip==0)
			update(1,C[which[v1]].size(),1,dec[which[v1]-1]);
		if (tip==1)
		{
			rez=0; 
			while (which[v1]!=which[v2])
			{
				if (lvl[ dad[ which[v1] ] ] < lvl[ dad[ which[v2] ] ])
					swap(v1,v2);
				p1=1; p2=where[v1];
				rez=max(rez,search(1,C[which[v1]].size(),1,dec[which[v1]-1]));
				v1=dad[which[v1]];
			}
			
			if (where[v1]>where[v2]) swap(v1,v2);
			p1=where[v1]; p2=where[v2];
			rez=max(rez,search(1,C[which[v1]].size(),1,dec[which[v1]-1]));
			
			printf("%d\n",rez);
		}
	}
}
int main()
{
	freopen("heavypath.in","r",stdin);
	freopen("heavypath.out","w",stdout);
	read();
	dfs(1);
	cons();
	solve();
	return 0;
}