Cod sursa(job #1131219)

Utilizator axnsanCristi Vijdea axnsan Data 28 februarie 2014 18:34:13
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#ifdef __INFOARENA_PROJ
#include "infoarena.h"
#endif

#include <fstream>
#include <algorithm>

#ifdef __INFOARENA_PROJ
namespace arbint {
#endif

const unsigned int nMax = 100000;
template <size_t N> struct log2_
{
	enum { value = 1 + log2_<N / 2>::value };
};

template <> struct log2_<1>
{
	enum { value = 0 };
};

	template <size_t N> struct pow2_
	{
		enum { value = 2 * pow2_<N - 1>::value };
	};

	template <> struct pow2_<0>
	{
		enum { value = 1 };
	};

class ArboreDeMax {
public:
	ArboreDeMax(unsigned N) : N(N) { }
	void adaugare(unsigned index, unsigned val) { _actualizare(1, 1, N, index, val); }
	void actualizare(unsigned index, unsigned val) { _actualizare(1, 1, N, index, val); }
	unsigned maximInInterval(unsigned a, unsigned b) { return _interogareMax(1, 1, N, a, b); }

private:
	unsigned V[pow2_<log2_<nMax>::value + 2>::value + 1], N;
	void _actualizare(unsigned nod, unsigned st, unsigned dr, unsigned index, unsigned val)
	{
		if (st == dr && dr == index)
			V[nod] = val;
		else
		{
			unsigned mij = (st + dr) / 2;
			if (index <= mij)
				_actualizare(2 * nod, st, mij, index, val);
			else _actualizare(2 * nod + 1, mij + 1, dr, index, val);
			V[nod] = std::max(V[2 * nod], V[2 * nod + 1]);
		}
	}
	unsigned _interogareMax(unsigned nod, unsigned st, unsigned dr, unsigned a, unsigned b)
	{
		if (st == a && dr == b)
			return V[nod];
			

		unsigned mij = (st + dr) / 2;
		if (b <= mij)
			return _interogareMax(2 * nod, st, mij, a, b);
		if (a > mij)
			return _interogareMax(2 * nod + 1, mij + 1, dr, a, b);
		return std::max(_interogareMax(2 * nod, st, mij, a, mij), 
			_interogareMax(2 * nod + 1, mij + 1, dr, mij + 1, b));
	}
};

int main()
{
	std::ifstream in("arbint.in");
	std::ofstream out("arbint.out");
	unsigned N, M, op, a, b;
	in >> N >> M;
	ArboreDeMax *A = new ArboreDeMax(N);
	for (unsigned i = 1; i <= N; ++i)
	{
		in >> a;
		A->adaugare(i, a);
	}
	for (unsigned i = 1; i <= M; ++i)
	{
		in >> op >> a >> b;
		if (op == 0)
			out << A->maximInInterval(a, b) << '\n';
		if (op == 1)
			A->actualizare(a, b);
	}
	return 0;
}

#ifdef __INFOARENA_PROJ
}
#endif