Cod sursa(job #615671)

Utilizator drywaterLazar Vlad drywater Data 10 octombrie 2011 15:24:18
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.18 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN=100010;
ifstream f("heavypath.in");
ofstream o("heavypath.out");
vector <int> G[MAXN],P[MAXN];
int rez,aux,sol,fol[MAXN],w[MAXN],nl,aint[4*MAXN];
int x,y,n,m,v[MAXN],i,niv[MAXN],lant[MAXN],parent[MAXN],poz[MAXN],dim[MAXN],lNiv[MAXN];
struct operatie{int t; int x; int y;};
operatie op[MAXN];
int df(int nod)
{
	w[nod]=1;
	fol[nod]=1;
	int frunza=1,he=-1;
	for (vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
	{
		if (fol[*it]) continue;
		frunza=0;
		niv[*it]=niv[nod]+1;
		df(*it);
		w[nod]+=w[*it];
		if (he==-1)
			he=*it;
		else if (w[he]<w[*it]) he=*it;
	}
	if (frunza)
	{
		lant[nod]=++nl;
		++dim[nl];
		P[nl].push_back(nod);
		return 0;
	}
	lant[nod]=lant[he];
	++dim[lant[he]];
	P[lant[he]].push_back(nod);
	for (vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
	{
		if (*it==he || niv[*it]<niv[nod])
			continue;
		parent[lant[*it]]=nod;
		lNiv[lant[*it]]=nod;
	}
	return 0;
}
int build(int nod,int st,int dr,int decalaj,int lan)
{
	if (st==dr)
	{
		aint[nod+decalaj]=v[P[lan][st-1]];
		return 0;
	}
	int med=(st+dr)/2;
	build(nod*2,st,med,decalaj,lan);
	build(nod*2+1,med+1,dr,decalaj,lan);
	aint[nod+decalaj]=aint[nod*2+decalaj];
	if (aint[nod+decalaj]<aint[nod*2+1+decalaj]) aint[nod+decalaj]=aint[nod*2+1+decalaj];
	return 0;
}
int update(int nod,int st,int dr,int poz,int val,int decalaj)
{
	if (st==dr)
	{
		aint[nod+decalaj]=val;
		return 0;
	}
	int med=(st+dr)/2;
	if (poz<=med)
		update(nod*2,st,med,poz,val,decalaj);
	else update(nod*2+1,med+1,dr,poz,val,decalaj);
	aint[nod+decalaj]=aint[nod*2+decalaj];
	if (aint[nod+decalaj]<aint[nod*2+1+decalaj])
		aint[nod+decalaj]=aint[nod*2+1+decalaj];
	return 0;
}
int query(int nod,int st,int dr,int qst,int qdr,int decalaj)
{
	if (qst<=st && qdr>=dr)
		return aint[nod+decalaj];
	int med=(st+dr)/2;
	if (qst<=med)
	{
		aux=query(nod*2,st,med,qst,qdr,decalaj);
		if (rez<aux) rez=aux;
	}
	if (qdr>med)
	{
		aux=query(nod*2+1,med+1,dr,qst,qdr,decalaj);
		if (rez<aux) rez=aux;
	}
	return rez;
}
int main(void)
{
	f>>n>>m;
	for (i=1;i<=n;i++) f>>v[i];
	for (i=1;i<n;i++)
	{
		f>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for (i=1;i<=m;i++)
		f>>op[i].t>>op[i].x>>op[i].y;
	niv[1]=1;
	df(1);
	for (i=1;i<=nl;i++)
	{
		reverse(P[i].begin(),P[i].end());
		if (i>1)
			poz[i]=poz[i-1]+4*dim[i-1];
		build(1,1,dim[i],poz[i],i);
	}
	for (i=1;i<=m;i++)
	{
		x=op[i].x;
		y=op[i].y;
		if (op[i].t==0)
			update(1,1,dim[lant[x]],niv[x]-lNiv[lant[x]],y,poz[lant[x]]);
		else
		{
			sol=0;
			while (1)
			{
				if (lant[x]==lant[y])
				{
					if (niv[x]>niv[y])
					{
						aux=y;
						y=x;
						x=aux;
					}
					rez=0;
					aux=query(1,1,dim[lant[x]],niv[x]-lNiv[lant[x]],niv[y]-lNiv[lant[x]],poz[lant[x]]);
					if (sol<aux) sol=aux;
					break;

				}
				if (lNiv[lant[x]]<lNiv[lant[y]])
				{
					aux=y;
					y=x;
					x=aux;
				}
				rez=0;
				aux=query(1,1,dim[lant[x]],1,niv[x]-lNiv[lant[x]],poz[lant[x]]);
				if (sol<aux) sol=aux;
				x=parent[lant[x]];
			}
			o<<sol<<"\n";
		}
	}
return 0;
}