Problem 8: Segment Tree with Lazy Propagation
Problem Statement: Implement a segment tree with lazy propagation to support range updates and range queries on an array.
Input
The first line contains n (number of elements) and q (number of queries). The next line has n integers. Each query is either "update l r v" or "query l r".
Output
For each query command "query", output the computed result (e.g., sum) for the range.
Examples
Input:
5 3\n1 2 3 4 5\nupdate 1 3 2\nquery 0 4\nquery 1 2
Output:
17\n7
Solution in C++
#include <iostream>
#include <vector>
using namespace std;
struct SegmentTree{
int n;
vector<long long> tree, lazy;
SegmentTree(int n): n(n) {
tree.assign(4*n, 0);
lazy.assign(4*n, 0);
}
void build(vector<int>& arr, int idx, int l, int r){
if(l == r){
tree[idx] = arr[l]; return;
}
int mid = (l+r)/2;
build(arr, 2*idx, l, mid);
build(arr, 2*idx+1, mid+1, r);
tree[idx] = tree[2*idx] + tree[2*idx+1];
}
void update(int idx, int l, int r, int ql, int qr, int val){
if(lazy[idx] != 0){
tree[idx] += (r-l+1)*lazy[idx];
if(l != r){
lazy[2*idx] += lazy[idx];
lazy[2*idx+1] += lazy[idx];
}
lazy[idx] = 0;
}
if(r < ql || l > qr) return;
if(ql <= l && r <= qr){
tree[idx] += (r-l+1)*val;
if(l != r){
lazy[2*idx] += val;
lazy[2*idx+1] += val;
}
return;
}
int mid = (l+r)/2;
update(2*idx, l, mid, ql, qr, val);
update(2*idx+1, mid+1, r, ql, qr, val);
tree[idx] = tree[2*idx] + tree[2*idx+1];
}
long long query(int idx, int l, int r, int ql, int qr){
if(lazy[idx] != 0){
tree[idx] += (r-l+1)*lazy[idx];
if(l != r){
lazy[2*idx] += lazy[idx];
lazy[2*idx+1] += lazy[idx];
}
lazy[idx] = 0;
}
if(r < ql || l > qr) return 0;
if(ql <= l && r <= qr) return tree[idx];
int mid = (l+r)/2;
return query(2*idx, l, mid, ql, qr) + query(2*idx+1, mid+1, r, ql, qr);
}
};
int main(){
int n, q;
cin >> n >> q;
vector<int> arr(n);
for(int i=0;i<n;i++) cin >> arr[i];
SegmentTree st(n);
st.build(arr, 1, 0, n-1);
while(q--) {
string op;
cin >> op;
if(op == "update"){
int l, r, v;
cin >> l >> r >> v;
st.update(1, 0, n-1, l, r, v);
} else {
int l, r;
cin >> l >> r;
cout << st.query(1, 0, n-1, l, r) << "\n";
}
}
return 0;
}