Cod sursa(job #2369214)

Utilizator usureluflorianUsurelu Florian-Robert usureluflorian Data 5 martie 2019 21:45:52
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
ifstream f("heavypath.in");
ofstream fout("heavypath.out");
const int nmax=1e5+5;
int n,m,val[nmax],x,y,caz,cnt[nmax],nr,fz[nmax],ant2[nmax],ant[nmax],arb[4*nmax],niv[nmax],de[nmax],ls,ld,sol,poz;
vector <int> v[nmax];
void dfs(int nod)
{
	int ok=1,sol=0,z;
	cnt[nod]=1;
	for(int i=0;i<v[nod].size();++i)
    {
        int urm=v[nod][i];
        if(urm!=ant[nod])
		{
			ant[urm]=nod;
			niv[urm]=niv[nod]+1;
			dfs(urm);
			cnt[nod]+=cnt[urm];
			ok=0;
			if(cnt[urm]>sol)
			{
				sol=cnt[urm];
				z=urm;
			}
		}
    }
	if(ok)
	{
		++nr;
		fz[nod]=nr;
		return;
	}
	for(int i=0;i<v[nod].size();++i)
    {
        int urm=v[nod][i];
        if(urm!=ant[nod]&&urm!=z) ant2[fz[urm]]=nod;
    }
	fz[nod]=fz[z];
}
void update(int nod,int st,int dr,int pup)
{
	if(st==dr)
	{
		arb[nod+pup]=y;
		return;
	}
	int mij=(st+dr)/2;
	if(poz<=mij) update(2*nod,st,mij,pup);
	else update(2*nod+1,mij+1,dr,pup);
	arb[nod+pup]=max(arb[2*nod+pup],arb[2*nod+1+pup]);
}
void update(int nod)
{
	poz=niv[nod]-niv[ant2[fz[nod]]];
	update(1,1,cnt[fz[nod]],de[fz[nod]]);
}
void query(int nod,int st,int dr,int pup)
{
	if(ls<=st&&dr<=ld)
	{
		sol=max(sol,arb[nod+pup]);
		return;
	}
	int mij=(st+dr)/2;
	if(ls<=mij) query(2*nod,st,mij,pup);
	if(mij<ld) query(2*nod+1,mij+1,dr,pup);
}
void solve(int x,int y)
{
	while(niv[x]>=niv[y])
	{
		ls=max(1,niv[y]-niv[ant2[fz[x]]]);
		ld=niv[x]-niv[ant2[fz[x]]];
		query(1,1,cnt[fz[x]],de[fz[x]]);
		x=ant2[fz[x]];
	}
}
int lca(int x,int y)
{
	while(fz[x]!=fz[y])
    {
        if(niv[ant2[fz[x]]]>=niv[ant2[fz[y]]]) x=ant2[fz[x]];
        else y=ant2[fz[y]];
    }
    if(niv[x]<=niv[y]) return x;
    return y;
}
int main()
{
    ios::sync_with_stdio(false);
	f>>n>>m;
	for(int i=1;i<=n;++i) f>>val[i];
	for(int i=1;i<n;++i)
	{
		f>>x>>y;
		v[x].pb(y);
		v[y].pb(x);
	}
	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)
	{
		y=val[i];
		update(i);
	}
	while(m--)
	{
		f>>caz;
		if(!caz)
		{
			f>>x>>y;
			update(x);
			continue;
		}
		f>>x>>y;
		sol=0;
		int k=lca(x,y);
		solve(x,k);
		solve(y,k);
		fout<<sol<<'\n';
	}
	return 0;
}