#include <bits/stdc++.h>
using namespace std;
// _TYPE = {int, long long, double, float}
template <class _TYPE>
class Segment_Tree {
private:
struct TreeNode;
public:
int _SIZE;
TreeNode* root;
Segment_Tree() {}
Segment_Tree(int _SIZE, vector<_TYPE> &_NUMS): _SIZE(_SIZE) {root = BuildTree(0, _SIZE - 1, _NUMS);}
_TYPE sum(int _LEFT, int _RIGHT) {return Query(root, _LEFT, _RIGHT);}
void add(int _LEFT, int _RIGHT, _TYPE _NUMS) {Modify(root, _LEFT, _RIGHT, _NUMS);}
private:
struct TreeNode {
int _LEFT, _RIGHT, size;
_TYPE val, tmp;
TreeNode *left, *right;
TreeNode() {}
TreeNode(int __LEFT, int __RIGHT, int _val): _LEFT(__LEFT), _RIGHT(__RIGHT), val(_val), left(nullptr), right(nullptr), tmp(0) {
size = __RIGHT - __LEFT + 1;
}
TreeNode(int __LEFT, int __RIGHT, int _val, TreeNode *_left, TreeNode *_right): _LEFT(__LEFT), _RIGHT(__RIGHT), val(_val), left(_left), right(_right), tmp(0) {
size = __RIGHT - __LEFT + 1;
}
};
TreeNode *BuildTree(int _LEFT, int _RIGHT, vector<_TYPE> &_NUMS) {
int _MID = (_LEFT + _RIGHT) / 2;
if (_LEFT == _RIGHT)
return new TreeNode(_LEFT, _RIGHT, _NUMS[_MID]);
TreeNode *_left = BuildTree(_LEFT, _MID, _NUMS), *_right = BuildTree(_MID + 1, _RIGHT, _NUMS);
return new TreeNode(_LEFT, _RIGHT, _left->val + _right->val, _left, _right);
}
void push_down(TreeNode *node) {
node->val += node->tmp * node->size;
if (node->left != nullptr && node->right != nullptr) {
node->left->tmp += node->tmp;
node->right->tmp += node->tmp;
}
node->tmp = 0;
}
_TYPE Query(TreeNode *node, int _LEFT, int _RIGHT) {
if (_LEFT > _RIGHT)
return _TYPE(0);
push_down(node);
int _MID = (node->_LEFT + node->_RIGHT) / 2;
if (node->_LEFT == _LEFT && node->_RIGHT == _RIGHT)
return node->val;
if (_MID < _LEFT)
return Query(node->right, _LEFT, _RIGHT);
else if (_RIGHT <= _MID)
return Query(node->left, _LEFT, _RIGHT);
else
return Query(node->left, _LEFT, _MID) + Query(node->right, _MID + 1, _RIGHT);
}
void Modify(TreeNode *node, int _LEFT, int _RIGHT, _TYPE _NUMS) {
if (node->_LEFT == _LEFT && node->_RIGHT == _RIGHT) {
node->tmp += _NUMS;
push_down(node);
return;
}
push_down(node);
int _MID = (node->_LEFT + node->_RIGHT) / 2;
if (_MID < _LEFT)
Modify(node->right, _LEFT, _RIGHT, _NUMS);
else if (_RIGHT <= _MID)
Modify(node->left, _LEFT, _RIGHT, _NUMS);
else
Modify(node->left, _LEFT, _MID, _NUMS), Modify(node->right, _MID + 1, _RIGHT, _NUMS);
push_down(node->left), push_down(node->right);
node->val = node->left->val + node->right->val;
}
};
09-20
01-20