Cod sursa(job #2734271)

Utilizator FrostfireMagirescu Tudor Frostfire Data 31 martie 2021 17:08:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100000

using namespace std;

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

int n, q, k, value[NMAX+10], label[NMAX+10], head[NMAX+10], heavyChild[NMAX+10], nivel[NMAX+10], tata[NMAX+10], sz[NMAX+10], poz;
int aint[4*NMAX+10];
vector <int> nod[NMAX+10];

void dfs_init(int x, int p)
{	int maxChildSize = 0;
	nivel[x] = nivel[p] + 1;
	tata[x] = p;
	sz[x] = 1;
	for(auto u : nod[x])
		if(u != p)
			{	dfs_init(u, x);
				sz[x] += sz[u];
				if(sz[u] > maxChildSize)
					{	maxChildSize = sz[u];
						heavyChild[x] = u;
					}
			}
}

void dfs_decomposition(int x, int h, int p)
{	head[x] = h;
	label[x] = ++poz;
	if(heavyChild[x])
		dfs_decomposition(heavyChild[x], h, x);
	for(auto u : nod[x])
		if(u != p && u != heavyChild[x])
			dfs_decomposition(u, u, x);
}

void init()
{	int bit = 0;
	while((1 << bit) < n)
		bit++;
	k = (1 << bit);
	for(int i=1; i<=n; i++)
		aint[label[i]+k-1] = value[i];
	for(int i=k-1; i; i--)
		aint[i] = max(aint[2*i], aint[2*i+1]);
}

void update(int poz, int val)
{	poz = poz + k - 1;
	aint[poz] = val;
	poz /= 2;
	while(poz)
		{	aint[poz] = max(aint[2*poz], aint[2*poz+1]);
			poz /= 2;
		}
}

int query(int nod, int stnod, int drnod, int stq, int drq)
{	if(stq <= stnod && drnod <= drq)
		return aint[nod];
	int mij = (stnod + drnod) / 2, ans = 0;
	if(stq <= mij)
		ans = max(ans, query(2*nod, stnod, mij, stq, drq));
	if(drq > mij)
		ans = max(ans, query(2*nod+1, mij+1, drnod, stq, drq));
	return ans;
}

int solve(int a, int b)
{	int ans = 0;
	while(head[a] != head[b])
		{	if(nivel[head[a]] < nivel[head[b]])
				swap(a, b);
			ans = max(ans, query(1, 1, k, label[head[a]], label[a]));
			a = tata[head[a]];
		}
	if(nivel[a] < nivel[b])
		swap(a, b);
	ans = max(ans, query(1, 1, k, label[b], label[a]));
	return ans;
}

int main()
{
	fin >> n >> q;
	for(int i=1; i<=n; i++)
		fin >> value[i];
	for(int i=1; i<n; i++)
		{	int nod1, nod2;
			fin >> nod1 >> nod2;
			nod[nod1].push_back(nod2);
			nod[nod2].push_back(nod1);
		}
	dfs_init(1, 0);
	dfs_decomposition(1, 1, 0);
	init();
	while(q--)
		{	int type, a, b;
			fin >> type >> a >> b;
			if(!type)
				{	//update
					update(label[a], b);
				}
			else
				{	//query
					fout << solve(a, b) << '\n';
				}
		}
	return 0;
}