Cod sursa(job #974759)

Utilizator tudorv96Tudor Varan tudorv96 Data 18 iulie 2013 11:42:12
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.84 kb
#include <fstream>
#include <vector>
#include <list>
#include <algorithm>
#include <iostream>
using namespace std;

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

#define oo -0x3f3f3f3f

vector <vector <int> > g, p;
vector <int> v, lv, nod, tata, loc, gap, arb;
vector <bool> viz, done;
int n, m, tp = 1;

void update (int nod, int lo, int hi, int pos, int val, int gap) {
	if (lo == hi) {
		arb[nod+gap] = val;
		return;
	}
	int mid = (lo + hi) >> 1;
	if (pos <= mid)
		update (nod << 1, lo, mid, pos, val, gap);
	else
		update ((nod << 1) + 1, mid+1, hi, pos, val, gap);
	arb[nod+gap] = max (arb[(nod << 1) + gap], arb[(nod << 1) + 1 + gap]);
}

int query (int nod, int lo, int hi, int qlo, int qhi, int gap) {
	if (qlo <= lo && hi <= qhi)
		return arb[nod+gap];
	int mid = (lo + hi) >> 1, res = oo;
	if (qlo <= mid)
		res = max(res, query (nod << 1, lo, mid, qlo, qhi, gap));
	if (qhi > mid)
		res = max(res, query ((nod << 1) + 1, mid + 1, hi, qlo, qhi, gap));
	return res;
}

bool cmp(int a, int b) {
	return nod[a] > nod[b];
}

void Resize() {
	viz.resize(n+1); done.resize(n+1);
	g.resize(n+1); p.resize(n+1);
	v.resize(n+1); lv.resize(n+1); nod.resize(n+1);
	tata.resize(n+1); loc.resize(n+1); gap.resize(n+1);
	arb.resize(4*(n+2));
}

void dfs(int x, int val) {
	viz[x] = 1;
	nod[x]++;
	lv[x] = val;
	for (vector <int> :: iterator it = g[x].begin(); it != g[x].end(); ++it)
		if (!viz[*it]) {
			dfs(*it, val + 1);
			nod[x] += nod[*it];
		}
}

void Heavy_Path (int x, int path) {
	viz[x] = 0;
	loc[x] = path;
	p[path].push_back(x);
	for (vector <int> :: iterator it = g[x].begin(); it != g[x].end(); ++it)
		if (viz[*it]) {
			if (!done[x]) {
				done[x] = 1;
				Heavy_Path(*it, path);
			}
			else {
				tata[++tp] = x;
				Heavy_Path(*it, tp);
			}
		}
}	

int main() {
	fin >> n >> m;
	Resize();
	for (int i = 1; i <= n; ++i)
		fin >> v[i];
	for (int i = 1; i < n; ++i) {
		int x, y;
		fin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1, 1);
	for (int i = 1; i <= n; ++i)
		sort(g[i].begin(), g[i].end(), cmp);
	Heavy_Path(1, 1);
	for (int i = 1; i <= tp; ++i) {
		gap[i] = gap[i-1] + p[i-1].size() * 4;
		for (vector <int> :: iterator it = p[i].begin(); it != p[i].end(); ++it)
			update (1, 1, p[i].size(), lv[*it] - lv[tata[loc[*it]]], v[*it], gap[i]);
	}
	while (m--) {
		bool t;
		int x, y;
		fin >> t >> x >> y;
		if (!t) {
			v[x] = y;
			update (1, 1, p[loc[x]].size(), lv[x] - lv[tata[loc[x]]], y, gap[loc[x]]);
		}
		else {
			int sol = oo;
			while (loc[x] != loc[y]) {
				if (lv[tata[loc[x]]] < lv[tata[loc[y]]])
					swap(x,y);
				sol = max (sol, query(1, 1, p[loc[x]].size(), 1, lv[x] - lv[tata[loc[x]]], gap[loc[x]]));
				x = tata[loc[x]];
			}
			if (lv[x] < lv[y])
				swap(x,y);
			sol = max (sol, query (1, 1, p[loc[x]].size(), lv[y] - lv[tata[loc[x]]], lv[x] - lv[tata[loc[x]]], gap[loc[x]]));
			fout << sol << "\n";
		}
	}
	fcloseall();
}