打包一个珂朵莉送给你~


Chtholly Tree (ODT)


/**
 * author: Gyan083  inaku.gs
 * 
 * 2021.10.24
 * 
 * 
 */



/** @file include/Chtholly.cpp
 *  This is a Non-standard C++ header.
 */


#ifndef _CHTHOLLY
#define _CHTHOLLY 1

#include <set>
#include <functional>



namespace __ODT_
{



	
	 
template<typename Tp, typename comp = std::equal_to<Tp> >
/**
 * comp(a,b) to decide if they can be merged
 * std::equal_to<_Tp> comes from <functional> (stl_function.h)
 *
 */
  class Chtholly {
  	
  	
  	
  	public:
  		
  		
  		class iterator;//declare iterator
  		
  		
  		
  		
  		
	private:
		
		
		struct node {//nodes in the set
			const int l;
			mutable int r;
			mutable Tp val;
			node() = delete;//for safety
			node(int L) : l(L) { }//for convenience
			node(int L, int R, const Tp& V) : l(L), r(R), val(V) { }
			bool operator < (const node& y) const {//for set's comparison
				return l < y.l;
			}
		};
		
		std::set<node> st;
		
		typedef typename std::set<node>::iterator IT;
		
		int _size_n;
		iterator _begin_iterator, _end_iterator;
		
		IT split(int pos) {
			if (pos<1) return st.begin();//A programmer get into a bar...
			IT it(std::prev(st.upper_bound(pos)));
			if (it->r < pos) return st.end();//Another programmer get into the bar...
			if (it->l == pos) return it;
			int tmpr = it->r;
			it->r = pos - 1;
			return st.insert(node(pos, tmpr, it->val)).first;
		}
		
		IT merge(IT i) {
			IT l(i), r(i);//caution: [l,r)
			while (l != st.begin()
				&& comp()(prev(l)->val, i->val)
				) --l;
			while (r != st.end()
				&& comp()(r->val, i->val)
				) ++r;
			int tl(l->l), tr(prev(r)->r);
			Tp tv(i->val);
			if (tl>tr) return i;//
			st.erase(l, r);
			return st.insert(node(tl, tr, tv)).first;
		}
		
		void merge(IT l, IT r) {//[l,r]
			int ed(r->r);
			while (l->r < ed) l=next(merge(l));
		}
		
		void merge()
		{ merge(st.begin(), --st.end()); }
		
		
		
		
		
	public:
		
		
		Chtholly()//an empty sequence
		: st(), _size_n(0),
			_begin_iterator(1, st.begin()), _end_iterator(_size_n+1, st.end())
		{ }
		
		Chtholly(int n, const Tp& val)
		: st(), _size_n(n)
		{
			st.insert(node(1, n, val));
			_begin_iterator = iterator(1, st.begin());
			_end_iterator = iterator(_size_n+1, st.end());
		}
		
		template<typename FI>
		  Chtholly(FI first, FI end)//copy value from [first,end)
		  : st(), _size_n(0)
		{
		  	if (first == end) return;
		  	Tp val(*first++);
		  	int l(1), r(1);
			while (first != end) {
				if ( !comp()(*first, val) ) {
					_size_n += r-l+1;
					st.insert(node(l, r, val));
					val = *first;
					l = r + 1;
				}
				++first, ++r;
			}
			_size_n += r-l+1;
			st.insert(node(l, r, val));
			
			_begin_iterator = iterator(1, st.begin());
			_end_iterator = iterator(_size_n+1, st.end());
		}
		
		void clear()
		{ st.clear(); }
		
		void rebuild()
		{ *this = Chtholly(); }
		
		void rebuild(int n, const Tp& val)
		{ *this = Chtholly(n, val); }
		
		template<typename FI>
		  void rebuild(FI first, FI end)
		{ *this = Chtholly(first, end); }
		
		void assign(int l, int r, const Tp& val) {//force to remake [l,r] val
			if (l>r) return;
			IT itr(split(r+1)), itl(split(l));
			st.erase(itl, itr);
			IT i = st.insert(node(l, r, val)).first;
			merge(i);
		}
		
		template<typename Rtn, typename... ArgList>
		  void operate(int l , int r, Rtn (*func)(iterator, ArgList...), ArgList... arg) {
			if (l>r) return;//The third programmer ask for a bunch of noodles...
			if (l<1) l = 1;
			if (r>size()) r = size();
			IT itr(split(r+1)), itl(split(l));
			for (IT it(itl); it!=itr; ++it) {
				func(iterator(it->l, it), arg...);
			}
			merge(itl, itr);
		}
		
		template<typename FI>//copy [l,r] to 'destin'
		  void copy_to(FI destin, int l, int r) const {
		  	if (l>r) return;
		  	IT it(--st.upper_bound(l));
		  	while (it != st.end()) {
		  		int lim(std::min(it->r, r));
		  		while (l <= lim) *destin++=it->val, ++l;
		  		if (l>r) return;
		  		++it;
			}
		}
		
		const Tp operator [] (const int pos) const//you shound not change its value
		{ return std::prev(st.upper_bound(pos))->val; }
		//O(log n)
		
		int size() const//length of the real array
		{ return _size_n; }
		
		iterator begin() const
		{ return _begin_iterator; }
		
		iterator end() const
		{ return _end_iterator; }
		
		int bsize() const
		{ return st.size(); }
		
		
		
		
	class iterator {
		
		
		private:
			
			int pos;//iterator in the real array
			IT it;//iterator in set
			
			
			
		public:
			
			iterator() = default;//for safety
			
			iterator(int ind, const IT& i)
			: pos(ind), it(i) { }
			
			iterator operator ++ () {
				if (++pos > it->r) ++it;
				return *this;
			}
			iterator operator ++ (int) {
				iterator tmp = *this;
				return ++*this, tmp;
			}
			iterator operator -- () {
				if (--pos < it->l) --it;
				return *this;
			}
			iterator operator -- (int) {
				iterator tmp = *this;
				return --*this, tmp;
			}
			bool operator == (const iterator& _x) const { return pos == _x.pos; }
			bool operator != (const iterator& _x) const { return pos != _x.pos; }
			bool operator <  (const iterator& _x) const { return pos <  _x.pos; }
			bool operator >  (const iterator& _x) const { return pos >  _x.pos; }
			bool operator <= (const iterator& _x) const { return pos <= _x.pos; }
			bool operator >= (const iterator& _x) const { return pos >= _x.pos; }
			
			Tp& operator * () { return it->val; }
			const Tp val() { return **this; }
			const int left() const { return it->l; }
			const int right() const { return it->r; }
			iterator prev() const { return iterator(it->l - 1, std::prev(it)); }
			iterator next() const { return iterator(it->r + 1, std::next(it)); }
			
	};//class iterator
		
		
		
		
};//class Chtholly





}//namespace __ODT_




#endif // _CHTHOLLY


压缩版(仅有一行便于复制):

template<typename Tp,typename comp=std::equal_to<Tp>>class Chtholly{public:class iterator;private:struct node{const int l;mutable int r;mutable Tp val;node()=delete;node(int L):l(L){}node(int L,int R,const Tp&V):l(L),r(R),val(V){}bool operator<(const node&y)const{return l<y.l;}};std::set<node>st;typedef typename std::set<node>::iterator IT;int _size_n;iterator _begin_iterator,_end_iterator;IT split(int pos){if(pos<1)return st.begin();IT it(std::prev(st.upper_bound(pos)));if(it->r<pos)return st.end();if(it->l==pos)return it;int tmpr=it->r;it->r=pos-1;return st.insert(node(pos,tmpr,it->val)).first;}IT merge(IT i){IT l(i),r(i);while(l!=st.begin()&&comp()(prev(l)->val,i->val))--l;while(r!=st.end()&&comp()(r->val,i->val))++r;int tl(l->l),tr(prev(r)->r);Tp tv(i->val);if(tl>tr)return i;st.erase(l,r);return st.insert(node(tl,tr,tv)).first;}void merge(IT l,IT r){int ed(r->r);while(l->r<ed)l=next(merge(l));}void merge(){merge(st.begin(),--st.end());}public:Chtholly():st(),_size_n(0),_begin_iterator(1,st.begin()),_end_iterator(_size_n+1,st.end()){}Chtholly(int n,const Tp&val):st(),_size_n(n){st.insert(node(1,n,val));_begin_iterator=iterator(1,st.begin());_end_iterator=iterator(_size_n+1,st.end());}template<typename FI>Chtholly(FI first,FI end):st(),_size_n(0){if(first==end)return;Tp val(*first++);int l(1),r(1);while(first!=end){if(!comp()(*first,val)){_size_n+=r-l+1;st.insert(node(l,r,val));val=*first;l=r+1;}++first,++r;}_size_n+=r-l+1;st.insert(node(l,r,val));_begin_iterator=iterator(1,st.begin());_end_iterator=iterator(_size_n+1,st.end());}void clear(){st.clear();}void rebuild(){*this=Chtholly();}void rebuild(int n,const Tp&val){*this=Chtholly(n,val);}template<typename FI>void rebuild(FI first,FI end){*this=Chtholly(first,end);}void assign(int l,int r,const Tp&val){if(l>r)return;IT itr(split(r+1)),itl(split(l));st.erase(itl,itr);IT i=st.insert(node(l,r,val)).first;merge(i);}template<typename Rtn,typename...ArgList>void operate(int l,int r,Rtn(*func)(iterator,ArgList...),ArgList...arg){if(l>r)return;if(l<1)l=1;if(r>size())r=size();IT itr(split(r+1)),itl(split(l));for(IT it(itl);it!=itr;++it){func(iterator(it->l,it),arg...);}merge(itl,itr);}template<typename FI>void copy_to(FI destin,int l,int r)const{if(l>r)return;IT it(--st.upper_bound(l));while(it!=st.end()){int lim(std::min(it->r,r));while(l<=lim)*destin++=it->val,++l;if(l>r)return;++it;}}const Tp operator[](const int pos)const{return std::prev(st.upper_bound(pos))->val;}int size()const{return _size_n;}iterator begin()const{return _begin_iterator;}iterator end()const{return _end_iterator;}int bsize()const{return st.size();}class iterator{private:int pos;IT it;public:iterator()=default;iterator(int ind,const IT&i):pos(ind),it(i){}iterator operator++(){if(++pos>it->r)++it;return*this;}iterator operator++(int){iterator tmp=*this;return++*this,tmp;}iterator operator--(){if(--pos<it->l)--it;return*this;}iterator operator--(int){iterator tmp=*this;return--*this,tmp;}bool operator==(const iterator&_x)const{return pos==_x.pos;}bool operator!=(const iterator&_x)const{return pos!=_x.pos;}bool operator<(const iterator&_x)const{return pos<_x.pos;}bool operator>(const iterator&_x)const{return pos>_x.pos;}bool operator<=(const iterator&_x)const{return pos<=_x.pos;}bool operator>=(const iterator&_x)const{return pos>=_x.pos;}Tp&operator*(){return it->val;}const Tp val(){return**this;}const int left()const{return it->l;}const int right()const{return it->r;}iterator prev()const{return iterator(it->l-1,std::prev(it));}iterator next()const{return iterator(it->r+1,std::next(it));}};};

请及时向我反映 bug ,谢谢。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM