Cod sursa(job #823042)

Utilizator unholyfrozenCostea Andrei unholyfrozen Data 24 noiembrie 2012 15:27:48
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

class arbint {
	static const int MIN_VALUE;
	struct node {
		int left_child, right_child;
		int max_value;
		int start_elem, end_elem;
		
		node() {
			left_child = right_child = -1;
			max_value = arbint::MIN_VALUE;
			start_elem = end_elem = -1;
		}
	};

	node* tree;
	const int num_nodes;
	
	void set_ranges(int elem, int start, int end) {
		if (start > end)
			return;

		tree[elem].start_elem = start;
		tree[elem].end_elem = end;
		tree[elem].left_child = (elem << 1) | 1;
		tree[elem].right_child = (elem << 1) + 2;
		set_ranges(tree[elem].left_child, start, (start + end) >> 1);
		set_ranges(tree[elem].right_child, ((start + end) >> 1) + 1, end);
		if(tree[tree[elem].left_child].start_elem == -1)
			tree[elem].left_child = -1;
		if(tree[tree[elem].right_child].start_elem == -1)
			tree[elem].right_child = -1;
	}

	void update(int elem, int mod_elem, int value) {
		if (tree[elem].start_elem == mod_elem &&
		    tree[elem].end_elem == mod_elem) {
			tree[elem].max_value = value;
			return;
		}
		int lChild, rChild;
		lChild = tree[elem].left_child;
		rChild = tree[elem].right_child;
	
		if (lChild != -1 && mod_elem <= tree[lChild].end_elem) {
			update(lChild, mod_elem, value);
			if (tree[elem].max_value < tree[lChild].max_value)
				tree[elem].max_value = tree[lChild].max_value;
		}
		else if (rChild != -1) {
			update(rChild, mod_elem, value);
			if (tree[elem].max_value < tree[rChild].max_value)
				tree[elem].max_value = tree[rChild].max_value;
		     }
	}

	int query(int elem, int start, int end) {
		int start_elem = tree[elem].start_elem;
		int end_elem = tree[elem].end_elem;
		int lChild = tree[elem].left_child;
		int rChild = tree[elem].right_child;
		int result = MIN_VALUE;

		if (start <= start_elem && end_elem <= end)
			return tree[elem].max_value;
		if (lChild != -1 && start <= tree[lChild].end_elem)
			result = query(lChild, start, tree[lChild].end_elem);
		if (rChild != -1 && end >= tree[rChild].start_elem) {
			int right_res = query(rChild, tree[rChild].start_elem, end);
			if (result < right_res)
				result = right_res;
		}

		return result;
	}
public:
	
	arbint(int num_nodes) : num_nodes(num_nodes) {
		int size_tree;
		/* lowest power of two greater or equal to 2 * num_nodes */
		for (size_tree = 1; size_tree <= 2 * num_nodes; size_tree <<= 1);
		size_tree >>= 1;
		tree = new node[size_tree];
		set(
	}

	~arbint() {
		delete[] tree;
	}

	void set(int elem, int value) {
		update(0, elem, value);		
	}

	int ask(int start, int end) {
		return query(0, start, end);
	}
};

const int arbint::MIN_VALUE = -1;

int main()
{
	freopen("arbint.in", "r", stdin);
	freopen("arbint.out", "w", stdout);

	int num_elem, num_queries;
	cin >> num_elem >> num_queries;
	
	arbint A(num_elem);

	for (int i = 0; i < num_elem; i++) {
		int value;
		cin >> value;
		A.set(i, value);		
	}

 	for (int i = 0; i < num_queries; i++) {
		int type;
		int a, b;
		
		cin >> type >> a >> b;
		if (type == 0)
			cout << A.ask(a, b) << endl;
		else
			A.set(a, b);	
	}

	return 0;
}