orz今天写了三遍
另外我只写了区间修改和求和。为啥呢?因为我菜啊qwq
#include#include #define maxn 200001#define int long longusing namespace std;int n, m;int sum[maxn*2], add[maxn*2]; void build(){ for(m=1; m<=n; m<<=1); for(int i=m+1; i<=m+n; i++) scanf("%lld", &sum[i]); for(int i=m-1; i; i--) sum[i]=sum[i<<1]+sum[i<<1|1];}inline int query_part(int s, int t){ int lc=0, rc=0, len=1, ans=0; for(s+=m-1, t+=m+1; s^t^1; s>>=1, t>>=1, len<<=1){ if(s&1^1) ans+=sum[s^1]+len*add[s^1], lc+=len; if(t&1) ans+=sum[t^1]+len*add[t^1], rc+=len; if(add[s>>1]) ans+=add[s>>1]*lc; if(add[t>>1]) ans+=add[t>>1]*rc; } s>>=1; for(lc+=rc; s; s>>=1) if(add[s]) ans+=add[s]*lc; return ans;}inline int update(int s, int t, int v){ int lc=0, rc=0, len=1; for(s+=m-1, t+=m+1; s^t^1; s>>=1, t>>=1, len<<=1){ if(s&1^1) add[s^1]+=v, lc+=len; if(t&1) add[t^1]+=v, rc+=len; sum[s>>1]+=v*lc, sum[t>>1]+=v*rc; } for(lc+=rc; s; s>>=1) sum[s>>1]+=v*lc;}int q;signed main(){ scanf("%lld%lld", &n, &q); build(); int qwq, x, y, k; while(q--){ scanf("%lld", &qwq); if(qwq==1){ scanf("%lld%lld%lld", &x, &y, &k); update(x, y, k); }else{ scanf("%lld%lld", &x, &y); printf("%lld\n", query_part(x, y)); } } return 0;}