Cod sursa(job #3365753)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 23 septembrie 2026 20:02:01
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 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 STN
{
	int x;

	friend STN operator+(STN a, STN b)
	{
		return {std::max(a.x, b.x)};
	}
};

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

#define left n+1
#define right n+(mid-l+1)*2

	void init(int _N, int* _v)
	{
		N=_N;
		init(0, 0, N-1, _v);
	}
	void init(int n, int l, int r, int* _v)
	{
		if(l==r)
			v[n].x=_v[l];
		else
		{
			int mid=(l+r)/2;
			init(left, l, mid, _v);
			init(right, mid+1, r, _v);
			v[n]=v[left]+v[right];
		}
	}

	void update(int p, int x)
	{
		update(0, 0, N-1, p, x);
	}
	void update(int n, int l, int r, int p, int x)
	{
		if(l==r)
			v[n].x=x;
		else
		{
			int mid=(l+r)/2;
			if(p<=mid)
				update(left, l, mid, p, x);
			else
				update(right, mid+1, r, p, x);
			v[n]=v[left]+v[right];
		}
	}

	STN query(int l, int r)
	{
		return query(0, 0, N-1, l, r);
	}
	STN query(int n, int l, int r, int ql, int qr)
	{
		if(ql<=l && r<=qr)
			return v[n];
		int mid=(l+r)/2;
		if(ql<=mid && mid<qr)
			return query(left, l, mid, ql, qr)+query(right, mid+1, r, ql, qr);
		if(ql<=mid)
			return query(left, l, mid, ql, qr);
		return query(right, mid+1, r, ql, qr);
	}

#undef left
#undef right
};

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]).x);
		a=tt[chain[a]];
	}

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

	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;
}