区间求和最值
class SegmentTree {
public:
SegmentTree(const vector<int>& data, int mod = 1e12) : n(data.size()) {
this -> data = data;
this -> mod = mod;
tree.resize(4 * n);
lazy_add.assign(4 * n, 0);
lazy_mul.assign(4 * n, 1);
build(0, 0, n - 1);
}
//区间修改 范围(此处[1, n]) 修正值 加减 true|乘除false
void update_range(int l, int r, int value, bool op) {
update_range(0, 0, n - 1, l - 1, r - 1, value, op);
}
//区间查询求和
int query_range(int l, int r) {
return query_range(0, 0, n - 1, l - 1, r - 1) % mod;
}
//单点修改 目标点 目标值
void update_point(int idx, int value) {
update_point(0, 0, n - 1, idx - 1, value);
}
//返回[l,r]区间最小值
int range_min(int l, int r) {
return range_min(0, 0, n - 1, l - 1, r - 1);
}
//返回[l,r]区间最大值
int range_max(int l, int r) {
return range_max(0, 0, n - 1, l - 1, r - 1);
}
private:
vector<int> data, tree;
vector<int> lazy_add, lazy_mul;
int n, mod;
void build(int node, int start, int end) {
if (start == end) {
tree[node] = data[start];
}
else
{
int mid = (start + end) / 2;
build((node << 1) + 1, start, mid);
build((node << 1) + 2, mid + 1, end);
tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];
}
}
void apply_lazy(int node, int start, int end) {
if (lazy_mul[node] != 1)
{
tree[node] = tree[node] * lazy_mul[node] % mod;
if (start != end) {
lazy_mul[(node << 1) + 1] = lazy_mul[(node << 1) + 1] * lazy_mul[node] % mod;
lazy_mul[(node << 1) + 2] = lazy_mul[(node << 1) + 2] * lazy_mul[node] % mod;
lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] * lazy_mul[node] % mod;
lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] * lazy_mul[node] % mod;
}
lazy_mul[node] = 1;
}
if (lazy_add[node] != 0)
{
tree[node] = tree[node] + (end - start + 1) * lazy_add[node] % mod;
if (start != end) {
lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] + lazy_add[node] % mod;
lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] + lazy_add[node] % mod;
}
lazy_add[node] = 0;
}
}
void update_range(int node, int start, int end, int l, int r, int value, bool op)
{
apply_lazy(node, start, end);
if(start > end || start > r || end < l) return;
if (start >= l && end <= r)
{
if (op == true)
{
lazy_add[node] = lazy_add[node] + value % mod; // Add
}
else if (op == false)
{
lazy_mul[node] = lazy_mul[node] * value % mod; // Multiply
lazy_add[node] = lazy_add[node] * value % mod; // Adjust for additive effect of multiplier
}
apply_lazy(node, start, end);
return;
}
int mid = (start + end) / 2;
update_range((node << 1) + 1, start, mid, l, r, value, op);
update_range((node << 1) + 2, mid + 1, end, l, r, value, op);
tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];
}
int query_range(int node, int start, int end, int l, int r) {
apply_lazy(node, start, end);
if (start > end || start > r || end < l) {
return 0;
}
if (start >= l && end <= r) {
return tree[node] % mod;
}
int mid = (start + end) >> 1;
return query_range((node << 1) + 1, start, mid, l, r) % mod + query_range((node << 1) + 2, mid + 1, end, l, r) % mod;
}
void update_point(int node, int start, int end, int idx, int value) {
if (start == end) {
tree[node] = value;
} else {
int mid = (start + end) / 2;
if (start <= idx && idx <= mid) {
update_point((node << 1) + 1, start, mid, idx, value);
} else {
update_point((node << 1) + 2, mid + 1, end, idx, value);
}
tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];
}
}
int range_min(int node, int start, int end, int l, int r) {
apply_lazy(node, start, end);
if (start > end || start > r || end < l) {
return numeric_limits<int>::max();
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) / 2;
return min(range_min((node << 1) + 1, start, mid, l, r),
range_min((node << 1) + 2, mid + 1, end, l, r));
}
int range_max(int node, int start, int end, int l, int r) {
apply_lazy(node, start, end);
if (start > end || start > r || end < l) {
return numeric_limits<int>::min();
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) / 2;
return max(range_max((node << 1) + 1, start, mid, l, r), range_max((node << 1) + 2, mid + 1, end, l, r));
}
};
区间修改求和
class SegmentTree {
public:
SegmentTree(const vector<int>& data, int mod = 1e12) : n(data.size()) {
this -> data = data;
this -> mod = mod;
tree.resize(4 * n);
lazy_add.assign(4 * n, 0);
lazy_mul.assign(4 * n, 1);
build(0, 0, n - 1);
}
//区间修改 范围(此处[1, n]) 修正值 加减 true|乘除false
void update_range(int l, int r, int value, bool op) {
update_range(0, 0, n - 1, l - 1, r - 1, value, op);
}
//区间查询求和
int query_range(int l, int r) {
return query_range(0, 0, n - 1, l - 1, r - 1) % mod;
}
//单点修改 目标点 目标值
void update_point(int idx, int value) {
update_point(0, 0, n - 1, idx - 1, value);
}
private:
vector<int> data, tree;
vector<int> lazy_add, lazy_mul;
int n, mod;
void build(int node, int start, int end) {
if (start == end) {
tree[node] = data[start];
}
else
{
int mid = (start + end) / 2;
build((node << 1) + 1, start, mid);
build((node << 1) + 2, mid + 1, end);
tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];
}
}
void apply_lazy(int node, int start, int end) {
if (lazy_mul[node] != 1)
{
tree[node] = tree[node] * lazy_mul[node] % mod;
if (start != end) {
lazy_mul[(node << 1) + 1] = lazy_mul[(node << 1) + 1] * lazy_mul[node] % mod;
lazy_mul[(node << 1) + 2] = lazy_mul[(node << 1) + 2] * lazy_mul[node] % mod;
lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] * lazy_mul[node] % mod;
lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] * lazy_mul[node] % mod;
}
lazy_mul[node] = 1;
}
if (lazy_add[node] != 0)
{
tree[node] = tree[node] + (end - start + 1) * lazy_add[node] % mod;
if (start != end) {
lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] + lazy_add[node] % mod;
lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] + lazy_add[node] % mod;
}
lazy_add[node] = 0;
}
}
void update_range(int node, int start, int end, int l, int r, int value, bool op)
{
apply_lazy(node, start, end);
if(start > end || start > r || end < l) return;
if (start >= l && end <= r)
{
if (op == true)
{
lazy_add[node] = lazy_add[node] + value % mod; // Add
}
else if (op == false)
{
lazy_mul[node] = lazy_mul[node] * value % mod; // Multiply
lazy_add[node] = lazy_add[node] * value % mod; // Adjust for additive effect of multiplier
}
apply_lazy(node, start, end);
return;
}
int mid = (start + end) / 2;
update_range((node << 1) + 1, start, mid, l, r, value, op);
update_range((node << 1) + 2, mid + 1, end, l, r, value, op);
tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];
}
int query_range(int node, int start, int end, int l, int r) {
apply_lazy(node, start, end);
if (start > end || start > r || end < l) {
return 0;
}
if (start >= l && end <= r) {
return tree[node] % mod;
}
int mid = (start + end) >> 1;
return query_range((node << 1) + 1, start, mid, l, r) % mod + query_range((node << 1) + 2, mid + 1, end, l, r) % mod;
}
void update_point(int node, int start, int end, int idx, int value) {
if (start == end) {
tree[node] = value;
} else {
int mid = (start + end) / 2;
if (start <= idx && idx <= mid) {
update_point((node << 1) + 1, start, mid, idx, value);
} else {
update_point((node << 1) + 2, mid + 1, end, idx, value);
}
tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];
}
}
};
单点修改求最小值
class SegmentTree {
private:
vector<int> tree; // 存储线段树
vector<int> data; // 原始数据
int n;
// 构建线段树
void build(int node, int start, int end) {
if (start == end) {
tree[node] = data[start]; // 叶子节点
} else {
int mid = (start + end) / 2;
build(2 * node + 1, start, mid); // 左子树
build(2 * node + 2, mid + 1, end); // 右子树
tree[node] = min(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果
}
}
// 修改某个点的值
void update(int node, int start, int end, int idx, int val) {
if (start == end) {
data[idx] = val; // 更新原始数据
tree[node] = val; // 更新线段树
} else {
int mid = (start + end) / 2;
if (idx <= mid) {
update(2 * node + 1, start, mid, idx, val); // 更新左子树
} else {
update(2 * node + 2, mid + 1, end, idx, val); // 更新右子树
}
tree[node] = min(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果
}
}
int range_min(int node, int start, int end, int l, int r)
{
if (start > end || start > r || end < l) {
return numeric_limits<int>::max();
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) / 2;
return min(range_min((node << 1) + 1, start, mid, l, r),
range_min((node << 1) + 2, mid + 1, end, l, r));
}
public:
SegmentTree(const vector<int>& arr) {
data = arr;
n = arr.size();
tree.resize(4 * n); // 线段树的大小
build(0, 0, n - 1); // 构建线段树
}
void update(int idx, int val) {
update(0, 0, n - 1, idx - 1, val); // 更新值
}
int range_min(int L, int R) {
return range_min(0, 0, n - 1, L - 1, R - 1); // 查询范围的最小值
}
};
单点最大值
class SegmentTree {
private:
vector<int> tree; // 存储线段树
vector<int> data; // 原始数据
int n;
// 构建线段树
void build(int node, int start, int end) {
if (start == end) {
tree[node] = data[start]; // 叶子节点
} else {
int mid = (start + end) / 2;
build(2 * node + 1, start, mid); // 左子树
build(2 * node + 2, mid + 1, end); // 右子树
tree[node] = max(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果
}
}
// 修改某个点的值
void update(int node, int start, int end, int idx, int val) {
if (start == end) {
data[idx] = val; // 更新原始数据
tree[node] = val; // 更新线段树
} else {
int mid = (start + end) / 2;
if (idx <= mid) {
update(2 * node + 1, start, mid, idx, val); // 更新左子树
} else {
update(2 * node + 2, mid + 1, end, idx, val); // 更新右子树
}
tree[node] = max(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果
}
}
// 查询区间的最大值
int range_max(int node, int start, int end, int l, int r) {
//apply_lazy(node, start, end);
if (start > end || start > r || end < l) {
return numeric_limits<int>::min();
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) / 2;
return max(range_max((node << 1) + 1, start, mid, l, r), range_max((node << 1) + 2, mid + 1, end, l, r));
}
public:
SegmentTree(const vector<int>& arr) {
data = arr;
n = arr.size();
tree.resize(4 * n); // 线段树的大小
build(0, 0, n - 1); // 构建线段树
}
void update(int idx, int val) {
update(0, 0, n - 1, idx, val); // 更新值
}
int range_max(int L, int R) {
return range_max(0, 0, n - 1, L, R); // 查询范围的最大值
}
};