https://github.com/rsy56640/rsy_little_lib/tree/master/library_for_algorithm/SegmentTree
指针实现
class SegmentTree {
class SegmentTreeNode {
public:
int start, end, val;
SegmentTreeNode *left, *right;
SegmentTreeNode(int start, int end, int val) {
this->start = start;
this->end = end;
this->val = val;
this->left = this->right = nullptr;
}
};
public:
SegmentTree(const vector<int>& A, std::function<int(int, int)> f)
:func(f)
{
// do intialization if necessary
if (A.empty())return;
root = build(0, A.size() - 1, A);
}
int query(int start, int end) {
// write your code here
if (start > end)return 0;
return doQuery(root, start, end);
}
void modify(int index, int value) {
// write your code here
doModify(root, index, value);
}
private:
SegmentTreeNode* root;
std::function<int(int, int)> func;
SegmentTreeNode* build(int start, int end, const vector<int>& v)
{
if (start == end)
return new SegmentTreeNode(start, end, v[start]);
int mid = (start + end) / 2;
SegmentTreeNode* node = new SegmentTreeNode(start, end, 0);
node->left = build(start, mid, v);
node->right = build(mid + 1, end, v);
node->val = func(node->left->val, node->right->val);
return node;
}
int doQuery(SegmentTreeNode* root, int start, int end)
{
if (start > root->end || end < root->start)
return 0;
if (start <= root->start && root->end <= end)
return root->val;
int mid = (root->start + root->end) / 2;
return func(doQuery(root->left, start, end), doQuery(root->right, start, end));
}
void doModify(SegmentTreeNode* root, int index, int value)
{
if (root->start == root->end && root->start == index)
{
root->val = value;
return;
}
int mid = (root->start + root->end) / 2;
if (index <= mid)
{
doModify(root->left, index, value);
root->val = func(root->left->val, root->right->val);
}
else
{
doModify(root->right, index, value);
root->val = func(root->left->val, root->right->val);
}
}
};
数组实现
template<typename _Ty>
class SegmentTree {
struct SegmentTreeNode
{
int start, end;
_Ty val;
SegmentTreeNode(int start, int end, _Ty val) {
this->start = start;
this->end = end;
this->val = val;
}
};
public:
SegmentTree(const vector<_Ty>& Vec,
std::function<_Ty(const _Ty&, const _Ty&)> func,
_Ty Identity_Element)
:_size(1),
_Func(func),
_Identity_Element(Identity_Element)
{
// do intialization if necessary
if (Vec.empty())return;
find_size(Vec.size());
ST.resize(2 * _size - 1);
build(0, 0, _size - 1, Vec);
}
_Ty query(int start, int end) const
{
return doQuery(0, start, end);
}
void modify(int index, _Ty value)
{
doModify(0, index, (value));
}
protected:
int _size;
vector<SegmentTreeNode*> ST;
std::function<_Ty(const _Ty&, const _Ty&)> _Func;
_Ty _Identity_Element;
private:
//find_size
void find_size(int size)
{
while (_size < size)
{
_size <<= 1;
}
}
//SegmentTree Initialization
void build(int index, int start, int end, const vector<_Ty>& Vec)
{
//leaf node
if (start == end)
{
ST[index] = new SegmentTreeNode(start, end,
(start < Vec.size()) ? Vec[start] : _Identity_Element);
return;
}
//internal node (non-leaf)
int mid = (start + end) / 2;
//construct this node with initial val(_Identity_Element)
ST[index] = new SegmentTreeNode(start, end, _Identity_Element);
//construct left and right subTree (recursion)
build((index << 1) + 1, start, mid, Vec);
build((index << 1) + 2, mid + 1, end, Vec);
//set value
ST[index]->val = _Func(ST[(index << 1) + 1]->val,
ST[(index << 1) + 2]->val);
}
//index: cur_node
_Ty doQuery(int index, int start, int end) const
{
//no segment union
if (start > ST[index]->end || end < ST[index]->start)
return _Identity_Element;
//querying segment includes root segment
if (start <= ST[index]->start && ST[index]->end <= end)
return ST[index]->val;
//partially coincide
return _Func(doQuery((index << 1) + 1, start, end),
doQuery((index << 1) + 2, start, end));
}
//index: cur_node //_index: modified_node
void doModify(int index, int _index, _Ty value)
{
//leaf node found
if (ST[index]->start == ST[index]->end && ST[index]->start == _index)
{
ST[index]->val = (value);
return;
}
//not found
int mid = (ST[index]->start + ST[index]->end) / 2;
//left subTree
if (_index <= mid)
{
doModify((index << 1) + 1, _index, value);
ST[index]->val = _Func(ST[(index << 1) + 1]->val,
ST[(index << 1) + 2]->val);
}
//right subTree
else
{
doModify((index << 1) + 2, _index, value);
ST[index]->val = _Func(ST[(index << 1) + 1]->val,
ST[(index << 1) + 2]->val);
}
}
};