#include "iostream"
#include "cstdio"
#include "cstdlib"
#include "cstring"
#include "cmath"
#include "algorithm"
#include "queue"
#include "vector"
#include "stack"
#include "map"
#include "set"
#include "climits"
using namespace std;
typedef long long ll;
typedef unsigned long long LL;
const int maxn = 100010;
const int INF = 0x3f3f3f3f;
ll tree[maxn << 2], lazy[maxn << 2], A[maxn];
int n, m;
void push_down(int node, int start, int end) {
if(lazy[node]) {
lazy[node << 1] += lazy[node];
lazy[node << 1 | 1] += lazy[node];
int mid = (start + end) >> 1;
tree[node << 1] += (mid - start + 1) * lazy[node];
tree[node << 1 | 1] += (end - mid) * lazy[node];
lazy[node] = 0;
}
}
void build(int node, int start, int end) {
if(start == end) {
tree[node] = A[start];
return ;
}
int mid = (start + end) >> 1;
build(node << 1, start, mid);
build(node << 1 | 1, mid + 1, end);
tree[node] = tree[node << 1] + tree[node << 1 | 1];
}
void update(int node, int start, int end, int L, int R, ll val) {
if(L <= start && R >= end) {
tree[node] += (end - start + 1) * val;
lazy[node] += val;
return ;
}
push_down(node, start, end);
int mid = (start + end) >> 1;
if(L <= mid) update(node << 1, start, mid, L, R, val);
if(R > mid) update(node << 1 | 1, mid + 1, end, L, R, val);
tree[node] = tree[node << 1] + tree[node << 1 | 1];
}
ll query(int node, int start, int end, int L, int R) {
if(L <= start && R >= end) return tree[node];
push_down(node, start, end);
ll ans = 0;
int mid = (start + end) >> 1;
if(L <= mid) ans += query(node << 1, start, mid, L, R);
if(R > mid) ans += query(node << 1 | 1, mid + 1, end, L, R);
return ans;
}
void Segment_Tree() {
cin >> n >> m;
for(int i = 1; i <= n; ++i) cin >> A[i];
build(1, 1, n);
for(int i = 0; i < m; ++i) {
int t;
cin >> t;
if(t == 1) {
ll l, r, val;
cin >> l >> r >> val;
update(1, 1, n, l, r, val);
}else {
ll l, r;
cin >> l >> r;
cout << query(1, 1, n, l, r) << endl;
}
}
}
int main() {
Segment_Tree();
return 0;
}
线段树区间更新、区间查询模板
最新推荐文章于 2021-11-26 12:23:39 发布