线段树
模板
(P3372 【模板】线段树 1)[https://www.luogu.com.cn/problem/P3372\]
cpp
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
typedef long long ll;
using namespace std;
const int N=100010;
struct node{
int l,r;
ll sum,add;
}tr[N*4];
int n,m;
int w[N];
void pushup(int u){
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void pushdown(int u){
node &root=tr[u],&left=tr[u<<1],&right=tr[u<<1|1];
if (root.add){
left.add+=root.add; left.sum+=(ll)(left.r-left.l+1)*root.add;
right.add+=root.add; right.sum+=(ll)(right.r-right.l+1)*root.add;
root.add=0;
}
}
void modify(int u,int l,int r,int d){
if (tr[u].l>=l&&tr[u].r<=r) {
tr[u].sum+=(ll)(tr[u].r-tr[u].l+1)*d;
tr[u].add+=d;
}
else {
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if (l<=mid) modify(u<<1,l,r,d);
if (r>mid) modify(u<<1|1,l,r,d);
pushup(u);
}
}
void build (int u,int l,int r){
if (l==r) tr[u]={l,r,w[r],0};
else{
tr[u]={l,r};
int mid=l+r>>1;
build (u<<1,l,mid);
build (u<<1|1,mid+1,r);
pushup(u);
}
}
ll query(int u,int l,int r){
if (tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
ll sum=0;
if (l<=mid )sum+=query(u<<1,l,r);
if (r>mid) sum+=query(u<<1|1,l,r);
return sum;
}
int main(){
cin>>n>>m;
for (int i=1;i<=n;i++){
cin>>w[i];
}
build (1,1,n);
for (int i=1;i<=m;i++){
int a,b,c,d;
cin>>a>>b>>c;
if (a==1){
cin>>d;
modify(1,b,c,d);
}
else{
cout<<query(1,b,c)<<endl;
}
}
return 0;
}