原题链接:https://www.acwing.com/problem/content/244/
线段树模板
#include <iostream>
#define ll long long
const ll N = 1e6;
struct ii{
ll l;
ll r;
ll v;
ll less;
}tree[N * 4];
ll op[N];
void pushup(ll xx){//向上遍历
tree[xx].v = tree[xx * 2].v + tree[xx * 2 + 1].v;
}
void pushdown(ll xx){//向下遍历
tree[xx * 2].v += tree[xx].less * (tree[xx * 2].r - tree[xx * 2].l + 1);
tree[xx * 2 + 1].v += tree[xx].less * (tree[xx * 2 + 1].r - tree[xx * 2 + 1].l + 1);
tree[xx * 2].less += tree[xx].less;
tree[xx * 2 + 1].less += tree[xx].less;
tree[xx].less = 0;
return ;
}
void built(ll l,ll r,ll x){//建树
if(l == r){
tree[x] = {l,r,op[l]};
return ;
} else{
tree[x] = {l,r};
}
ll mid = (l + r) / 2;
built(l,mid,x * 2);
built(mid + 1,r,x * 2 + 1);
pushup(x);//向上延伸
}
ll serch(ll aa,ll bb,ll cc){//求区域的和
if(tree[cc].l >= aa && tree[cc].r <= bb){
return tree[cc].v;
}
pushdown(cc);
ll mid = (tree[cc].l + tree[cc].r) / 2;
ll res = 0;
if(aa <= mid) res += serch(aa,bb,cc * 2);
if(bb > mid) res += serch(aa,bb,cc * 2 + 1);
return res;
}
void check(ll xx,ll aa,ll bb,ll cc){//改变数组当中的值
if(tree[xx].l >= aa && tree[xx].r <= bb){
tree[xx].v += (tree[xx].r - tree[xx].l + 1) * cc;
tree[xx].less += cc;
return ;
}
pushdown(xx);
ll mid = (tree[xx].l + tree[xx].r) / 2;
if(aa <= mid) check(xx * 2,aa,bb,cc);
if(bb > mid) check(xx * 2 + 1,aa,bb,cc);
pushup(xx);
return ;
}
void solve(){
ll n,m;
std::cin >> n >> m;
for(ll i = 1; i <= n; i ++) std::cin >> op[i];
built(1,n,1);
while(m --){
char a;
ll aa,bb,cc;
std::cin >> a;
if(a == 'Q'){//求和
std::cin >> aa >> bb;
std::cout << serch(aa,bb,1) << "\n";
} else{
std::cin >> aa >> bb >> cc;
check(1,aa,bb,cc);
}
}
}
int main(){
ll t = 1;
// std::cin >> t;
while(t --)
solve();
return 0;
}