dungceo
Rating
-
Bài tập
1
Điểm
1701
Rating #
-
Điểm #
16015
Giới thiệu
include <iostream>
include <vector>
using namespace std;
struct SegmentTree {
int n;
vector<long long> tree, lazyAdd, lazySet;
vector<bool> isSet;
SegmentTree(int size) : n(size), tree(4 * size), lazyAdd(4 * size), lazySet(4 * size), isSet(4 * size, false) {}
void push(int node, int start, int end) {
if (isSet[node]) {
tree[node] = (end - start + 1) * lazySet[node];
if (start != end) {
isSet[2 * node] = isSet[2 * node + 1] = true;
lazySet[2 * node] = lazySet[2 * node + 1] = lazySet[node];
lazyAdd[2 * node] = lazyAdd[2 * node + 1] = 0;
}
isSet[node] = false;
}
if (lazyAdd[node] != 0) {
tree[node] += (end - start + 1) * lazyAdd[node];
if (start != end) {
lazyAdd[2 * node] += lazyAdd[node];
lazyAdd[2 * node + 1] += lazyAdd[node];
}
lazyAdd[node] = 0;
}
}
void updateAdd(int node, int start, int end, int l, int r, long long val) {
push(node, start, end);
if (start > end || start > r || end < l) return;
if (start >= l && end <= r) {
lazyAdd[node] += val;
push(node, start, end);
return;
}
int mid = (start + end) / 2;
updateAdd(2 * node, start, mid, l, r, val);
updateAdd(2 * node + 1, mid + 1, end, l, r, val);
tree[node] = tree[2 * node] + tree[2 * node + 1];
}
void updateSet(int node, int start, int end, int l, int r, long long val) {
push(node, start, end);
if (start > end || start > r || end < l) return;
if (start >= l && end <= r) {
isSet[node] = true;
lazySet[node] = val;
lazyAdd[node] = 0;
push(node, start, end);
return;
}
int mid = (start + end) / 2;
updateSet(2 * node, start, mid, l, r, val);
updateSet(2 * node + 1, mid + 1, end, l, r, val);
tree[node] = tree[2 * node] + tree[2 * node + 1];
}
long long query(int node, int start, int end, int l, int r) {
push(node, start, end);
if (start > end || start > r || end < l) return 0;
if (start >= l && end <= r) return tree[node];
int mid = (start + end) / 2;
long long q1 = query(2 * node, start, mid, l, r);
long long q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 + q2;
}
void updateAdd(int l, int r, long long val) { updateAdd(1, 0, n - 1, l, r, val); }
void updateSet(int l, int r, long long val) { updateSet(1, 0, n - 1, l, r, val); }
long long query(int l, int r) { return query(1, 0, n - 1, l, r); }
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, q;
cin >> n >> q;
vector<int> arr(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
SegmentTree st(n);
for (int i = 0; i < n; i++) {
st.updateSet(i, i, arr[i]);
}
while (q--) {
int type;
cin >> type;
if (type == 1) {
int a, b, x;
cin >> a >> b >> x;
st.updateAdd(a - 1, b - 1, x);
} else if (type == 2) {
int a, b, x;
cin >> a >> b >> x;
st.updateSet(a - 1, b - 1, x);
} else if (type == 3) {
int a, b;
cin >> a >> b;
cout << st.query(a - 1, b - 1) << "\n";
}
}
return 0;
}