Cod sursa(job #3365751)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 23 septembrie 2026 19:52:53
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.18 kb
// Ilie "The-Winner" Dumitru
// Dumnezeu sa o ierte
#include<bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define err(...) fprintf(stderr, __VA_ARGS__)
using ll=long long;
using dbl=long double;
constexpr int NMAX=100'005;
constexpr ll MOD=1'000'000'007;

struct ST
{
	int N;
	int v[NMAX*2];

	void init(int _N, int* _v)
	{
		int i;

		N=_N;
		for(i=0;i<N;++i)
			v[i+N]=_v[i];
		for(i=N-1;i>0;--i)
			v[i]=std::max(v[i*2], v[i*2+1]);
	}

	void update(int p, int x)
	{
		for(v[p+=N]=x;p>0;p/=2)
			v[p/2]=std::max(v[p], v[p^1]);
	}

	int query(int l, int r)
	{
		int x=0;

		l+=N;
		r+=N+1;
		while(l<r)
		{
			if(l%2)
				x=std::max(x, v[l++]);
			if(r%2)
				x=std::max(x, v[--r]);

			l/=2;
			r/=2;
		}

		return x;
	}
};

int N;
int v[NMAX];
int tt[NMAX], dpt[NMAX], chain[NMAX];
std::vector<int> G[NMAX];
int sz[NMAX], poz[NMAX], cpoz;
ST S;

void dfs0(int n, int t=0)
{
	int i, max=0;

	dpt[n]=dpt[t]+1;
	tt[n]=t;
	sz[n]=1;

	for(i=0;i<sz(G[n]);++i)
	{
		if(G[n][i]==t)
		{
			G[n][i]=G[n].back();
			G[n].pop_back();
			--i;
		}
		else
		{
			dfs0(G[n][i], n);
			sz[n]+=sz[G[n][i]];
			if(sz[G[n][i]]>sz[G[n][max]])
				max=i;
		}
	}

	if(max)
		std::swap(G[n][0], G[n][max]);
}

void dfs1(int n)
{
	poz[n]=cpoz++;
	if(G[n].empty())
		return;
	chain[G[n][0]]=chain[n];
	dfs1(G[n][0]);
	for(int i=1;i<sz(G[n]);++i)
	{
		chain[G[n][i]]=G[n][i];
		dfs1(G[n][i]);
	}
}

int query(int a, int b)
{
	int ans=0;

	while(chain[a]!=chain[b])
	{
		if(dpt[a]<dpt[b])
			std::swap(a, b);

		ans=std::max(ans, S.query(poz[chain[a]], poz[a]));
		a=tt[chain[a]];
	}

	if(dpt[a]<dpt[b])
		std::swap(a, b);
	ans=std::max(ans, S.query(poz[b], poz[a]));

	return ans;
}

int main()
{
	FILE* f=fopen("heavypath.in", "r"), *g=fopen("heavypath.out", "w");
	int i, a, b, c, Q;

	fscanf(f, "%d%d", &N, &Q);
	for(i=0;i<N;++i)
		fscanf(f, "%d", v+i);
	for(i=1;i<N;++i)
	{
		fscanf(f, "%d%d", &a, &b);
		--a;
		--b;
		G[a].push_back(b);
		G[b].push_back(a);
	}

	dfs0(0);
	dfs1(0);

	for(i=0;i<N;++i)
		sz[poz[i]]=v[i];
	S.init(N, sz);

	do
	{
		fscanf(f, "%d%d%d", &a, &b, &c);
		if(a==0)
			S.update(poz[b-1], c);
		else
			fprintf(g, "%d\n", query(b-1, c-1));
	}while(--Q);

	fclose(f);
	fclose(g);
	return 0;
}