线段树模板
Posted PoorLitt1eThin9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树模板相关的知识,希望对你有一定的参考价值。
template <class T> class SegmentTree { public: T dat; int leftBorder = -1; int rightBorder = -1; SegmentTree * leftSon = NULL; SegmentTree * rightSon = NULL; void Build(T *, int, int, T (*)(T, T)); void Modify(int , T , T (*)(T, T)); T Query(int, int, T (*)(T, T)); void Free(); }; template<class T> void SegmentTree<T>::Build(T * S, int l, int r, T (* funptr)(T, T)) { if (l > r) { return; } leftBorder = l; rightBorder = r; if (l == r) { dat = S[l]; return; } int mid = (l + r) >> 1; leftSon = new SegmentTree; leftSon->Build(S, l, mid, funptr); rightSon = new SegmentTree; rightSon->Build(S, mid + 1, r, funptr); dat = funptr(leftSon->dat, rightSon->dat); } template<class T> void SegmentTree<T>::Modify(int pos, T NewDat, T (* funptr)(T, T)) { if (pos < leftBorder || rightBorder < pos) { return; } if (leftBorder == rightBorder) { dat = NewDat; return; } int mid = (leftBorder + rightBorder) >> 1; if (pos <= mid) { leftSon->Modify(pos, NewDat, funptr); } else { rightSon->Modify(pos, NewDat, funptr); } dat = funptr(leftSon->dat, rightSon->dat); } template<class T> T SegmentTree<T>::Query(int l, int r, T(* funptr)(T, T)) { if (l < leftBorder || rightBorder < l || r < leftBorder || rightBorder < r || l > r) { return dat; } if (l == leftBorder && r == rightBorder) { return dat; } int mid = (leftBorder + rightBorder) >> 1; if (mid < l) { return rightSon->Query(l, r, funptr); } if (r <= mid) { return leftSon->Query(l, r, funptr); } return funptr(leftSon->Query(l, mid, funptr), rightSon->Query(mid + 1, r, funptr)); } template<class T> void SegmentTree<T>::Free() { if (leftSon != NULL) { leftSon->Free(); } if (rightSon != NULL) { rightSon->Free(); } delete leftSon; delete rightSon; }
SegmentTree<T> Tree:线段树Tree,基础类型为T。
Tree.dat:该节点存储的信息。
Tree.leftBorder/rightBorder:该节点线段的左右端点。
Tree.leftSon/rightSon:该线段树的左右子树指针。
Tree.Build:对T类型数组S上从l到r的部分建立线段树,并使用funptr函数根据两子树的dat计算出该节点的dat。
Tree.Modify:将对应原数组pos位置的值修改为NewDat,并使用funptr函数调整相关节点的dat值。
Tree.Query:询问对应原数组从l到r部分的dat值。
Tree.Free:释放线段树所使用的内存。
funptr函数需要自己定义。
以上是关于线段树模板的主要内容,如果未能解决你的问题,请参考以下文章