数据结构:线段树
用于求 区间改变,区间求值问题。
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int n,m; int a[N],add[4*N]; long long sum[4*N]; void build(int l,int r,int k){ if(l==r){ sum[k]=a[l]; return ; } int mid=(l+r)>>1; build(l,mid,k<<1); build(mid+1,r,k<<1|1); sum[k]=sum[k<<1]+sum[k<<1|1]; } void ad(int l,int r,int k,int v){ add[k]+=v; sum[k]+=(long long)v*(r-l+1); } void pushdown(int l,int r,int k,int mid){ if(add[k]==0) return ; ad(l,mid,k<<1,add[k]); ad(mid+1,r,k<<1|1,add[k]); add[k]=0; } void modify(int l,int r,int x,int y,int v,int k){ if(l>=x && y>=r) return ad(l,r,k,v); int mid=(l+r)>>1; pushdown(l,r,k,mid); if(x<=mid) modify(l,mid,x,y,v,k<<1); if(y>mid) modify(mid+1,r,x,y,v,k<<1|1); sum[k]=sum[k<<1]+sum[k<<1|1]; } long long inquire(int l,int r,int x,int y,int k){ if(x<=l && r<=y) return sum[k]; int mid=(l+r)>>1; pushdown(l,r,k,mid); long long res=0; if(x<=mid) res+=inquire(l,mid,x,y,k<<1); if(y>mid) res+=inquire(mid+1,r,x,y,k<<1|1); return res; } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; build(1,n,1); for(int i=1;i<=m;i++){ int opt; cin>>opt; if(opt==1){ int x,y,v; cin>>x>>y>>v; modify(1,n,x,y,v,1); } else { int x,y; cin>>x>>y; cout<<inquire(1,n,x,y,1)<<endl; } } return 0; }