#ifndef SegmentTree_H__ #define SegmentTree_H__ namespace meow{ template inline SegmentTree::Node::Node(){ } template inline size_t SegmentTree::leftChild(size_t __parent) const { return __parent * 2 + 1; } template inline size_t SegmentTree::rightChild(size_t __parent) const { return __parent * 2 + 2; } template inline void SegmentTree::downUpdate(size_t __L, size_t __R, size_t __index){ size_t mid = (__L + __R) / 2; Value& val = _nodes[__index]._value; Value& off = _nodes[__index]._offset; if(_nodes[__index]._sameFlag){ if(__L < __R){ override(__L , mid, __L , mid, leftChild(__index), val); override(mid + 1, __R, mid + 1, __R, rightChild(__index), val); } _nodes[__index]._sameFlag = false; _nodes[__index]._offset = 0; }else if(!(_nodes[__index]._offset == Value(0))){ if(__L < __R){ offset(__L , mid, __L , mid, leftChild(__index), off); offset(mid + 1, __R, mid + 1, __R, rightChild(__index), off); } _nodes[__index]._offset = 0; } } template inline void SegmentTree::override(size_t __l, size_t __r, size_t __L, size_t __R, size_t __index, Value const& __value){ if(__l == __L && __r == __R){ _nodes[__index]._value = __value * (__R - __L + 1); _nodes[__index]._offset = 0; _nodes[__index]._sameFlag = true; return ; } downUpdate(__L, __R, __index); size_t mid = (__L + __R) / 2; if(__r <= mid){ override(__l, __r, __L , mid, leftChild(__index), __value); }else if(mid + 1 <= __l){ override(__l, __r, mid + 1, __R, rightChild(__index), __value); }else{ override(__l , mid, __L , mid, leftChild(__index), __value); override(mid + 1, __r, mid + 1, __R, rightChild(__index), __value); } _nodes[__index]._value = ( _nodes[ leftChild(__index)]._value | _nodes[rightChild(__index)]._value); } template inline void SegmentTree::offset(size_t __l, size_t __r, size_t __L, size_t __R, size_t __index, Value const& __delta){ if(__l == __L && __r == __R){ _nodes[__index]._value = _nodes[__index]._value + __delta*(__R-__L+1); if(!_nodes[__index]._sameFlag){ _nodes[__index]._offset = _nodes[__index]._offset + __delta; } return ; } downUpdate(__L, __R, __index); size_t mid = (__L + __R) / 2; if(__r <= mid){ offset(__l, __r, __L , mid, leftChild(__index), __delta); }else if(mid + 1 <= __l){ offset(__l, __r, mid + 1, __R, rightChild(__index), __delta); }else{ offset(__l , mid, __L , mid, leftChild(__index), __delta); offset(mid + 1, __r, mid + 1, __R, rightChild(__index), __delta); } _nodes[__index]._value = ( _nodes[ leftChild(__index)]._value | _nodes[rightChild(__index)]._value); } template inline Value SegmentTree::query(size_t __l, size_t __r, size_t __L, size_t __R, size_t __index){ if((__l == __L && __r == __R) || _nodes[__index]._sameFlag){ return _nodes[__index]._value; } size_t mid = (__L + __R) / 2; Value& off = _nodes[__index]._offset; if(__r <= mid){ return query(__l, __r, __L , mid, leftChild(__index)) + off; }else if(mid + 1 <= __l){ return query(__l, __r, mid + 1, __R, rightChild(__index)) + off; }else{ return ( query(__l , mid, __L , mid, leftChild(__index)) | query(mid + 1, __r, mid + 1, __R, rightChild(__index))) + off; } } template inline bool SegmentTree::rangeCorrect(ssize_t* __first, ssize_t* __last) const{ if(*__last < *__first){ return false; } if(*__last < 0 || _size - 1 < *__first){ return false; } *__first = inRange((ssize_t)0, (ssize_t)_size - 1, *__first); *__last = inRange((ssize_t)0, (ssize_t)_size - 1, *__last ); return true; } template inline SegmentTree::SegmentTree(): _size(0), _root(0) { } template inline SegmentTree::SegmentTree(size_t __size): _size(0), _root(0){ reset(__size); } template inline SegmentTree::SegmentTree(SegmentTree const& __tree2): _size(__tree2._size), _nodes(__tree2._nodes), _root(0){ } // template inline void SegmentTree::reset(size_t __size){ _size = __size; _nodes.resize(__size * 4); _nodes[_root]._sameFlag = true; _nodes[_root]._value = Value(0); } template inline Value SegmentTree::query(ssize_t __first, ssize_t __last) const{ if(rangeCorrect(&__first, &__last) == false){ return Value(); } return ((SegmentTree*)this)->query(__first, __last, 0, _size - 1, _root); } template inline void SegmentTree::override(ssize_t __first, ssize_t __last, Value const& __value){ if(rangeCorrect(&__first, &__last) == false){ return ; } override(__first, __last, 0, _size - 1, _root, __value); } template inline void SegmentTree::offset(ssize_t __first, ssize_t __last, Value const& __delta){ if(rangeCorrect(&__first, &__last) == false){ return ; } offset(__first, __last, 0, _size - 1, _root, __delta); } } #endif