Cod sursa(job #1576846)

Utilizator danalex97Dan H Alexandru danalex97 Data 22 ianuarie 2016 21:48:48
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.27 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

ifstream F("arbint.in");
ofstream G("arbint.out");

template <class T, int S>
class SegmentTree {
	private:
		T hold[S*5];
		T withValue[S*5];
		bool updated[S*5];
		
		int iBeg;
		int iEnd;
		T value;
		
		T neutral() {
			return T(0);
		}
		
		inline void _update_iBeg(int v) {
			iBeg = v;
		}
		
		inline void _update_iEnd(int v) {
			iEnd = v;
		}
		
		inline void _update_value(int v) {
			value = v;
		}
		
		inline int leftIdx(int node) {
			return node * 2;
		}
		inline int rightIdx(int node) {
			return node * 2 + 1;
		}
		T length(int left,int right) {
			return right - left + 1;
		}
		T app(T a, T b, int left, int right) {
			return a > b ? a : b;
		}
		
		void push(int node, int left, int right) {
			if ( !updated[node] ) 
				return;
			updated[node] = false;
			
			T nodeValue = withValue[node];
			int _leftIdx = leftIdx(node);
			int _rightIdx = rightIdx(node);
				
			hold[_leftIdx]  = nodeValue;
			hold[_rightIdx] = nodeValue;
				
			hold[node] = app(nodeValue, nodeValue, left, right);
			withValue[_leftIdx]  = nodeValue;
			withValue[_rightIdx] = nodeValue;
			
			updated[_leftIdx]  = true;
			updated[_rightIdx] = true;
		}
		
		inline bool isOutside(int left, int right) {
			return iBeg > right || iEnd < left;
		}
		
		inline bool isInside(int left, int right) {
			return iBeg <= left && right <= iEnd;
		}
		
		void _update(int node, int left, int right) {
			push(node, left, right);
			if ( isOutside(left, right) ) {
				return;
			}
			if ( isInside(left, right) ) {
				withValue[node] = value;
				updated[node] = true;
				push(node, left, right);
				return;
			}
			
			int middle    = (left + right) / 2;
			
			int _leftIdx = leftIdx(node);
			int _rightIdx = rightIdx(node);
			
			_update(_leftIdx, left, middle);
			_update(_rightIdx, middle+1 ,right);
			
			hold[node] = app(hold[_leftIdx], hold[_rightIdx], left, right);
		}
		
		T _query(int node, int left, int right) {
			push(node, left, right);
			if ( isOutside(left, right) ) {
				return neutral();
			}
			if ( isInside(left, right) ) {
				return hold[node];
			}
			int middle    = (left + right) / 2;
			
			int _leftIdx = leftIdx(node);
			int _rightIdx = rightIdx(node);
			
			T v1 = _query(_leftIdx, left, middle);
			T v2 = _query(_rightIdx, middle+1 ,right);
			
			hold[node] = app(hold[_leftIdx], hold[_rightIdx], left, right);
			return app(v1, v2, left, right); 
		}
	public:
		
		
		SegmentTree() {
			memset(hold,0,sizeof(hold));
			memset(withValue,0,sizeof(withValue));
			memset(updated,0,sizeof(updated));
			value = neutral();
			iBeg = iEnd = 0;
		}
		
		int size() {
			return S;
		}
		
		void update(int iBeg, int iEnd, T value) {
			_update_iBeg(iBeg);
			_update_iEnd(iBeg);
			_update_value(value);
			_update(1, 1, S);
		}
		
		T query(int iBeg, int iEnd) {
			_update_iBeg(iBeg);
			_update_iEnd(iEnd);
			return _query(1, 1, S);
		}
};

const int N = 100010;

SegmentTree<int,N> *seg = new SegmentTree<int,N>();

int n, m;

int main() {
	F >> n >> m;
	for (int i = 1, x; i <= n; ++i) {
		F >> x;
		seg -> update(i, i, x);
	}
	for (int i = 1, t, x, y; i <= m; ++i) {
		F >> t >> x >> y;
		if ( t == 1 ) {
			seg -> update(x, x, y);
		} else {
			int ans = seg -> query(x, y);
			G << ans << '\n';
		}
	}
}