Cod sursa(job #2416730)

Utilizator shantih1Alex S Hill shantih1 Data 27 aprilie 2019 23:10:43
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int nmx=100005;
int n,i,j,nr,m,np,x,y,op,k,sol;
int ct[nmx],v[nmx],t[nmx],pth[nmx],pos[nmx];

vector<int> ad[nmx];

struct Path
{
	int n,mx,tt,h;
	vector<int> nd,ai;
	
	void create()
	{
		ai.resize(4*n+5);
		build(1,1,n);
	}
	void build(int n,int l,int r)
	{
		if(l==r)
		{
			ai[n]=nd[l-1];
			return;
		}
		int m=(l+r)/2;
		build(2*n,l,m);
		build(2*n+1,m+1,r);
		ai[n]=max(ai[2*n],ai[2*n+1]);
	}
	void update(int p,int v)
	{
		change(1,1,n,p,v);
	}
	void change(int n,int l,int r,int p,int v)
	{
		if(l==r)
		{
			ai[n]=v;
			return;
		}
		int m=(l+r)/2;
		if(p<=m)	change(2*n,l,m,p,v);
		else		change(2*n+1,m+1,r,p,v);
		ai[n]=max(ai[2*n],ai[2*n+1]);
	}
	int query(int a,int b)
	{
		mx=0;
		maxim(1,1,n,a,b);
		return mx;
	}
	void maxim(int n,int l,int r,int a,int b)
	{
		if(a<=l && r<=b)
		{
			mx=max(mx, ai[n]);
			return;
		}
		int m=(l+r)/2;
		if(a<=m)	maxim(2*n,l,m,a,b);
		if(b>m)		maxim(2*n+1,m+1,r,a,b);
	}
} pa[nmx];

void dfs_cate(int n)
{
	ct[n]=1;
	for(int i:ad[n])
		if(!ct[i])
		{
			t[i]=n;
			dfs_cate(i);
			ct[n]+=ct[i];
		}
}

void make_paths(int n,int nw,int tt,int h)
{
	if(nw) {
		np++;
		pa[np].tt=tt;
		pa[np].h=h;
	}
	pa[np].n++;
	pa[np].nd.push_back(v[n]);
	
	pth[n]=np;
	pos[n]=(int)pa[np].nd.size();
	
	int id=0;
	for(int i:ad[n])
		if(i!=t[n] && ct[i]>ct[id])
			id=i;
	for(int i:ad[n])
		if(i!=t[n])
			make_paths(i, (i==id)?0:1, n, h+1);
}

int main() {
	
	fin>>n>>m;
	for(i=1;i<=n;i++)
		fin>>v[i];
	for(i=1;i<n;i++)
	{
		fin>>x>>y;
		ad[x].push_back(y);
		ad[y].push_back(x);
	}
	
	t[1]=0;
	dfs_cate(1);
	make_paths(1,1,0,1);
	
	for(i=1;i<=np;i++)
		pa[i].create();
	
	while(m--)
	{
		fin>>op>>x>>y;
		
		if(op==0)
			pa[pth[x]].update(pos[x], y);
		else
		{
			sol=0;
			while(1)
			{
				if(pth[x]==pth[y])
				{
					sol=max(sol, pa[pth[x]].query(min(pos[x],pos[y]), max(pos[x],pos[y])));
					break;
				}
				
				if(pa[pth[x]].h<pa[pth[y]].h)
					k=x, x=y, y=k;
				
				sol=max(sol, pa[pth[x]].query(1,pos[x]));
				
				x=pa[pth[x]].tt;
			}
			
			fout<<sol<<"\n";
		}
	}
}