题目链接 https://www.luogu.com.cn/problem/P3372
线段树区间求和区间修改模板题,复习一下数据结构。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define maxn 200005
int n, m;
LL a[maxn];
namespace sg {
#define ls o<<1
#define rs o<<1|1
#define mid (l + r)/2 // 这里写成 >>1会报错
LL t[maxn << 2], laz[maxn << 2];
void up(int o){ t[o] = t[ls] + t[rs]; }
void down(int o, int l, int r){
laz[ls] += laz[o]; laz[rs] += laz[o];
t[ls] += (mid - l + 1) * laz[o]; t[rs] += (r - mid) * laz[o];
laz[o] = 0;
}
template<typename T>
void build(T&& f, int o = 1, int l = 1, int r = n){
if ( l == r ) { t[o] = f[l]; return; }
build(f, ls, l, mid); build(f, rs, mid + 1, r);
up(o);
}
template<typename T>
void update(int o, int l, int r, int ql, int qr, T val){
down(o, l, r);
if ( ql <= l && r <= qr) {
t[o] += 1ll * (r - l + 1) * val;
laz[o] += val;
return;
}
if ( ql <= mid ) update(ls, l, mid, ql, qr, val);
if ( mid + 1 <= qr) update(rs, mid + 1, r, ql, qr, val);
up(o);
}
LL query(int o, int l, int r, int ql, int qr){
down(o, l, r);
if ( ql <= l && r <= qr ) return t[o];
LL ret = 0;
if ( ql <= mid ) ret += query(ls, l, mid, ql, qr);
if ( mid + 1 <= qr ) ret += query(rs, mid + 1, r, ql, qr);
return ret;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
sg::build(a);
int cmd, x, y;
LL z;
while(m--){
cin>>cmd;
if (cmd == 1){
cin>>x>>y>>z;
sg::update(1, 1, n, x, y, z);
}
else if (cmd == 2){
cin>>x>>y;
cout<<sg::query(1, 1, n, x, y)<<endl;
}
}
return 0;
}