Cod sursa(job #2313860)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 7 ianuarie 2019 15:44:16
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int M=100001;
int n,m,t,x,y,z,nrchain;
int v[M],h[M],s[M],ind[M],poz[M],nodes[M],pLant[M],arb[2*M];
vector<int> l[M],chain[M];
bool viz[M];
void dfs(int x,int p)
{
	int best = 0;
	h[x] = h[p] + 1;
	s[x] = 1;
	for(int i = 0; i < l[x].size(); ++i)
		if(l[x][i] != p)
		{
			dfs(l[x][i], x);
			s[x] += s[l[x][i]];
			if(s[best] < s[l[x][i]])
				best = l[x][i];
		}
	for(int i = 0; i < l[x].size(); ++i)
		if(l[x][i] != p && l[x][i] != best)
			pLant[ind[l[x][i]]] = x;
	if(best == 0)
		ind[x] = ++nrchain;
	else
		ind[x] = ind[best];
	chain[ind[x]].push_back(x);
}
void buildArb()
{
	for(int i = n; i > 0; --i)
		arb[i] = max(arb[2 * i], arb[2 * i + 1]);
}
void update(int pos,int val)
{
	pos += n;
	arb[pos] = val;
	for(; pos > 1; pos >>= 1)
		arb[pos>>1] = max(arb[pos], arb[pos ^ 1]);
}
int query(int x,int y)
{
	int res = 0;
	x += n;
	y += n;
	while(x < y)
	{
		if(x & 1)
			res = max(res, arb[x++]);
		if(y & 1)
			res = max(res, arb[--y]);
		x >>= 1;
		y >>= 1;
	}
	return res;
}
int hpd(int x,int y)
{
	int res = 0;
	while(ind[x] != ind[y])
	{
		if(h[pLant[ind[x]]] < h[pLant[ind[y]]])
			swap(x, y);
		res = max(res, query(poz[x], poz[chain[ind[x]].back()] + 1));
		x = pLant[ind[x]];
	}
	if(poz[x] > poz[y])
		swap(x, y);
	return max(res, query(poz[x], poz[y] + 1));
}
int main(){
	freopen("heavypath.in", "r", stdin);
	freopen("heavypath.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i)
		scanf("%d", &v[i]);
	for(int i = 0; i < n - 1; ++i)
	{
		scanf("%d%d", &x, &y);
		l[x].push_back(y);
		l[y].push_back(x);
	}
	dfs(1, 0);
	int nr = 0;
	for(int i = 1; i <= nrchain; ++i)
		for(int j = 0; j < chain[i].size(); ++j)
		{
			poz[chain[i][j]] = ++nr;
			nodes[nr] = chain[i][j];
			arb[nr + n] = v[chain[i][j]];
		}
	buildArb();
	for(int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &t, &x, &y);
		if(t == 0)
			update(poz[x], y);
		if(t == 1)
			printf("%d\n", hpd(x, y));
	}
}