Cod sursa(job #1976085)

Utilizator bt.panteaPantea Beniamin bt.pantea Data 2 mai 2017 18:51:29
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.07 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");

const int NMAX = 100005, MMAX = 100005, INF = 0x3f3f3f3f;
int n, m, value[NMAX], father[NMAX], niv[NMAX], w[NMAX];
int AI[4 * NMAX];
int lTata[NMAX], lNiv[NMAX], lDim[NMAX], lPoz[NMAX], nL, l[NMAX];
typedef vector<int>::iterator Iterator;

vector<int> a[NMAX], P[NMAX];

inline int max(const int & a, const int & b)
{
	if (a < b) return b;
	return a;
}

inline void DF(int nod)
{
	int hN = -1, frunza = 1;
	for (Iterator it = a[nod].begin(); it != a[nod].end(); it++) 
	{
		if (niv[*it] != 0)
			continue;
		frunza = 0;
		niv[*it] = niv[nod] + 1;
		DF(*it);
		w[nod] += w[*it];
		
		if(hN == -1)
			hN = *it;
		else if (w[hN] < w[*it])
			hN = *it;
	}
	
	if (frunza) 
	{
		l[nod] = ++nL;
		lDim[nL] = 1;
		P[nL].push_back(nod);
		return;
	}
	
	l[nod] = l[hN];
	lDim[l[nod]]++;
	P[l[nod]].push_back(nod);
	for (Iterator it = a[nod].begin(); it != a[nod].end(); ++it)
	{
		if (*it == hN || niv[*it] < niv[nod])
			continue;
		lTata[l[*it]] = nod;
		lNiv[l[*it]] = niv[nod];
	}
}

void build(int nod, int left, int right, int decalaj, int lant)
{
	if (left == right)
	{
		AI[nod + decalaj] = value[P[lant][left - 1]];
		return;
	}
	int mij = (left + right) / 2;
	build(2 * nod, left, mij, decalaj, lant);
	build(2 * nod + 1, mij + 1, right, decalaj, lant);
	AI[nod + decalaj] = max(AI[2 * nod + decalaj], AI[2 * nod + 1 + decalaj]);
}

inline void update(int nod, int left, int right, int poz, int val, int decalaj)
{
	if (left == right)	
	{
		AI[nod + decalaj] = val;
		return;
	}
	int mij = (left + right) / 2;
	if (poz <= mij)
		update(2 * nod, left, mij, poz, val, decalaj);
	else 
		update(2 * nod + 1, mij + 1, right, poz, val, decalaj);
	AI[nod + decalaj] = max(AI[2 * nod + decalaj], AI[2 * nod + 1 + decalaj]);
}

inline int query(int nod, int left, int right, int qleft, int qright, int decalaj)
{
	if (qleft <= left && qright >= right)
		return AI[nod + decalaj];
	
	int mij = (left + right) / 2;
	int rez = 0;
	
	if (qleft <= mij)
		rez = max(rez, query(2 * nod, left, mij, qleft, qright, decalaj));
	if (qright > mij)
		rez = max(rez, query(2 * nod + 1, mij + 1, right, qleft, qright, decalaj));
		
	return rez;
}

int main()
{
	f>>n>>m;
	for (int i = 1; i <= n; i++)
		f>>value[i];
	for (int x, y, i = 1; i < n; i++)
	{
		f>>x>>y;
		a[x].push_back(y);
		a[y].push_back(x);
	}
	niv[1] = 1;
	DF(1);
	for (int i = 1; i <= nL; i++) 
	{
		reverse(P[i].begin(), P[i].end());
		if (i > 1) 
			lPoz[i] = lPoz[i - 1] + lDim[i - 1] * 4;
			
		build(1, 1, lDim[i], lPoz[i], i);
	}
	
	while(m--) {
		int t, x, y;
		f>>t>>x>>y;
		if (t == 0) 
			update(1, 1, lDim[l[x]], niv[x] - lNiv[l[x]], y, lPoz[l[x]]);
		else {
			int sol = 0;
			while(true) {
				if (l[x] == l[y]) {
					if (niv[x] >  niv[y])
						swap(x, y);
					sol = max(sol, query(1, 1, lDim[l[x]], niv[x] - lNiv[l[x]], niv[y] - lNiv[l[x]], lPoz[l[x]]));
					break;
				}
				
				if (lNiv[l[x]] < lNiv[l[y]])
					swap(x, y);
				sol = max(sol, query(1, 1, lDim[l[x]], 1, niv[x] - lNiv[l[x]], lPoz[l[x]]));
				
				x = lTata[l[x]];
			}
			g<<sol<<'\n';
		}
	}
	return 0;
}