Cod sursa(job #1696078)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 28 aprilie 2016 13:31:15
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
using namespace std;
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#define Nmax 100001

int p, new_val, a, b;
int v[Nmax], h[Nmax];
int nrL, path[Nmax], p_father[Nmax], pos[Nmax], nr_nodes[Nmax];
vector< int > G[Nmax], aint[Nmax];

int DFS(int);
void update(vector<int>&, int, int, int);
int query(vector<int>&, int, int, int);

int main()
{
	int i, n, m, type, x, y, val, val_max;
	ifstream fin("heavypath.in");
	ofstream fout("heavypath.out");

	fin >> n >> m;
	for (i = 1; i <= n; ++i) fin >> v[i];

	for (i = 1; i < n; ++i)
	{
		fin >> x >> y;
		G[x].push_back(y);
		G[y].push_back(x);
	}

	h[1] = 1;
	DFS(1);
	p_father[path[1]] = 0;

	for (i = 1; i <= nrL; ++i) aint[i].resize(4 * nr_nodes[i]);
	for (i = 1; i <= n; ++i) { p = pos[i]; new_val = v[i]; update(aint[path[i]], 1, 1, nr_nodes[path[i]]); }
	
	for (i = 1; i <= m; ++i)
	{
		fin >> type >> x >> y;

		if (type == 0)
		{
			p = pos[x];
			new_val = y;
			update(aint[path[x]], 1, 1, nr_nodes[path[x]]);
		}
		else
		{
			val_max = 0;

			while (path[x] != path[y])
			{
				if (h[p_father[path[x]]] > h[p_father[path[y]]]) swap(x, y);

				a = pos[y];
				b = nr_nodes[path[y]];
				val = query(aint[path[y]], 1, 1, nr_nodes[path[y]]);
				y = p_father[path[y]];

				val_max = max(val_max, val);
			}

			a = min(pos[x], pos[y]);
			b = max(pos[x], pos[y]);
			val = query(aint[path[x]], 1, 1, nr_nodes[path[x]]);

			val_max = max(val_max, val);

			fout << val_max << '\n';
		}
	}

	fin.close();
	fout.close();
    return 0;
}

int DFS(int vf)
{
	int fiu, nr, nrmax, sum;
	bool leaf = true;

	fiu = 0;
	sum = nrmax = 0;

	for (auto &to : G[vf])
		if(!h[to])
		{
			h[to] = 1 + h[vf];
			
			nr = DFS(to);
			sum += nr;

			if (fiu == 0 || nr > nrmax) fiu = to, nrmax = nr;
			leaf = false;
		}

	for (auto &to : G[vf])
		if (h[to] == 1 + h[vf] && to != fiu)
			p_father[path[to]] = vf;

	if (leaf)
	{
		path[vf] = ++nrL;
		pos[vf] = 1;
		nr_nodes[nrL] = 1;
	}
	else
	{
		path[vf] = path[fiu];
		pos[vf] = 1 + pos[fiu];
		++nr_nodes[path[vf]];
	}

	return 1 + sum;
}

void update(vector<int> &aint, int node, int l, int r)
{
	if (l == r)
	{
		aint[node] = new_val;
		return;
	}

	int mid = (l + r) / 2;
	if (p <= mid) update(aint, 2 * node, l, mid);
	else update(aint, 2 * node + 1, mid + 1, r);

	aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}

int query(vector<int>& aint, int node, int l, int r)
{
	if (a <= l && r <= b) return aint[node];

	int v1 = 0, v2 = 0, mid = (l + r) / 2;
	if (a <= mid) v1 = query(aint, 2 * node, l, mid);
	if (b > mid) v2 = query(aint, 2 * node + 1, mid + 1, r);

	return max(v1, v2);
}