線段樹(模板)
阿新 • • 發佈:2020-08-28
#include<bits/stdc++.h> #define ll long long using namespace std; inline int read() { int x=0;int f=1;char c=getchar(); while(c<'0' || c>'9'){if(c=='-') f=0;c=getchar();} while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar(); return f?x:-x; } const int N=1e5+10; int a[N],n,m; struct SGT { int l,r; ll add,sum; }t[N<<2]; void build(int u,int l,int r) { t[u].l=l; t[u].r=r; if(l==r) { t[u].sum=a[l]; return; } int mid=(l+r)>>1; build((u<<1),l,mid); build(((u<<1)|1),mid+1,r); t[u].sum=t[(u<<1)].sum+t[((u<<1)|1)].sum; } void spread(int u) { if(t[u].add) { t[(u<<1)].add+=t[u].add; t[((u<<1)|1)].add+=t[u].add; t[(u<<1)].sum+=(t[(u<<1)].r-t[(u<<1)].l+1)*t[u].add; t[((u<<1)|1)].sum+=(t[((u<<1)|1)].r-t[((u<<1)|1)].l+1)*t[u].add; t[u].add=0; } } void modify(int u,int l,int r,int d) { if(l<=t[u].l && t[u].r<=r) { t[u].add+=d; t[u].sum+=(t[u].r-t[u].l+1)*d; return; } spread(u); int mid=(t[u].l+t[u].r)>>1; if(l<=mid) modify((u>>1),l,r,d); if(r>mid) modify(((u<<1)|1),l,r,d); t[u].sum=t[(u<<1)].sum+t[((u<<1)|1)].sum; } ll query(int u,int l,int r) { if(l<=t[u].l && t[u].r<=r) return t[u].sum; ll ans=0; spread(u); int mid=(t[u].l+t[u].r)>>1; if(l<=mid) ans+=query((u<<1),l,r); if(mid<r) ans+=query(((u<<1)|1),l,r); return ans; } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); build(1,1,n); for(int i=1;i<=m;i++) { int op=read(); if(op==1) { int l=read(),r=read(),d=read(); modify(1,l,r,d); } else { int l=read(),r=read(); printf("%lld\n",query(1,l,r)); } } return 0; }