Cod sursa(job #371806)

Utilizator c912046Mihaila Stefan c912046 Data 7 decembrie 2009 00:12:11
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <fstream>


//@TODO: find proper size of stree[]
unsigned int *vect, *stree, N;

#define LEFT(node) ((node<<1)+1)
#define RIGHT(node) ((node<<1)+2)

void init (unsigned int node, unsigned int l, unsigned int r);

int queryMax (unsigned int node, unsigned int l, unsigned int r,
	unsigned int ql, unsigned int qr);

void update (unsigned int node, unsigned int l, unsigned int r,
	unsigned int upd, unsigned int to);

int main ()
{
	std::ifstream f_in("arbint.in");
	std::ofstream f_out("arbint.out");
	
	unsigned int M, i, op, a, b;
	f_in >> N >> M;
	
	for (i = 0; i < N; ++i) f_in >> vect[i];
	
	vect  = new unsigned int[N];
	stree = new unsigned int[(N<<1)+1];
	
	init(0, 0, N-1);
	
	for (i = 0; i < M; ++i) {
		f_in >> op >> a >> b;
		if (!op) {
			--a; --b;
			f_out << queryMax(0, 0, N-1, a, b) << '\n';
		}
		else {
			--a;
			update(0, 0, N-1, a, b);
		}
	}
	
	f_in.close();
	f_out.close();
	return 0;
}

void init(unsigned int node, unsigned int l, unsigned int r)
{
	if (l == r) stree[node] = vect[l];
	else {
		unsigned int mid = (l+r)>>1;
		init(LEFT(node), l, mid);
		init(RIGHT(node), mid+1, r);
		
		if (stree[LEFT(node)] >= stree[RIGHT(node)])
			stree[node] = stree[LEFT(node)];
		else
			stree[node] = stree[RIGHT(node)];
	}
}

int queryMax (unsigned int node, unsigned int l, unsigned int r,
	unsigned int ql, unsigned int qr)
{
	if (r < ql || l > qr) return -1;
	
	if (l >= ql && r <= qr) return stree[node];
	
	unsigned int mid = (l+r)>>1;
	int q1 = queryMax(LEFT(node) , l    , mid, ql, qr),
		q2 = queryMax(RIGHT(node), mid+1, r  , ql, qr);
		
	return q1 > q2 ? q1 : q2;
}

void update (unsigned int node, unsigned int l, unsigned int r,
	unsigned int upd, unsigned int to)
{
	if (upd < l || upd > r) return;
	
	if (l == r) stree[node] = to;
	else {
		unsigned int mid = (l+r)>>1;
		if (upd <= mid) update(LEFT(node), l, mid, upd, to);
		else update(RIGHT(node), mid+1, r, upd, to);
		
		if (stree[LEFT(node)] >= stree[RIGHT(node)])
			stree[node] = stree[LEFT(node)];
		else
			stree[node] = stree[RIGHT(node)];
	}
}