Cod sursa(job #2367783)

Utilizator patcasrarespatcas rares danut patcasrares Data 5 martie 2019 12:13:58
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include<fstream>
#include<vector>
#include<algorithm>
#define pb push_back
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int DN=1e5+5;
int n,m,a[DN],f,g;
int type;
int cnt[DN],nr,fz[DN],pr2[DN],pr[DN];
int arb[4*DN],niv[DN],de[DN],ls,ld,ma;
int poz,val;
vector<int>v[DN];
void dfs(int nod)
{
	int frunza=1,ma=0,z;
	cnt[nod]=1;
	for(auto i:v[nod])
		if(i!=pr[nod])
		{
			pr[i]=nod;
			niv[i]=niv[nod]+1;
			dfs(i);
			cnt[nod]+=cnt[i];
			frunza=0;
			if(cnt[i]>ma)
			{
				ma=cnt[i];
				z=i;
			}
		}
	if(frunza)
	{
		nr++;
		fz[nod]=nr;
		return;
	}
	for(auto i:v[nod])
		if(i!=pr[nod]&&i!=z)
			pr2[fz[i]]=nod;
	fz[nod]=fz[z];
}
void update(int nod,int st,int dr,int decalaj)
{
	if(st==dr)
	{
		arb[nod+decalaj]=val;
		return;
	}
	int mij=(st+dr)/2;
	if(poz<=mij)
		update(2*nod,st,mij,decalaj);
	else
		update(2*nod+1,mij+1,dr,decalaj);
	arb[nod+decalaj]=max(arb[2*nod+decalaj],arb[2*nod+1+decalaj]);
}
void modifica(int nod)
{
	poz=niv[nod]-niv[pr2[fz[nod]]];
	update(1,1,cnt[fz[nod]],de[fz[nod]]);
}
void query(int nod,int st,int dr,int decalaj)
{
	if(ls<=st&&dr<=ld)
	{
		ma=max(ma,arb[nod+decalaj]);
		return;
	}
	int mij=(st+dr)/2;
	if(ls<=mij)
		query(2*nod,st,mij,decalaj);
	if(mij<ld)
		query(2*nod+1,mij+1,dr,decalaj);
}
void solve(int f,int g)
{
	while(niv[f]>=niv[g])
	{
		ls=max(1,niv[g]-niv[pr2[fz[f]]]);
		ld=niv[f]-niv[pr2[fz[f]]];
		query(1,1,cnt[fz[f]],de[fz[f]]);
		f=pr2[fz[f]];
	}
}
int lca(int f,int g)
{
	while(fz[f]!=fz[g])
    {
        if(niv[pr2[fz[f]]]>=niv[pr2[fz[g]]])
            f=pr2[fz[f]];
        else
            g=pr2[fz[g]];
    }
    if(niv[f]<=niv[g])
        return f;
    return g;
}
int main()
{
	fin>>n>>m;
	for(int i=1;i<=n;i++)
		 fin>>a[i];
	for(int i=1;i<n;i++)
	{
		fin>>f>>g;
		v[f].pb(g);
		v[g].pb(f);
	}
	niv[1]=1;
	dfs(1);
	for(int i=1;i<=n;i++)
        cnt[i]=0;
    for(int i=1;i<=n;i++)
        cnt[fz[i]]++;
	for(int i=1;i<=nr;i++)
		de[i]=de[i-1]+4*cnt[i-1];
	for(int i=1;i<=n;i++)
	{
		val=a[i];
		modifica(i);
	}
	while(m--)
	{
		fin>>type;
		if(type==0)
		{
			fin>>f>>val;
			modifica(f);
			continue;
		}
		fin>>f>>g;
		ma=0;
		int k=lca(f,g);
		solve(f,k);
		solve(g,k);
		fout<<ma<<'\n';
	}
}