#include<iostream> #include<cstdio> #include<cmath> using namespace std; int n,q; long long sum,a[200001]; struct tr { int l,r; long long v,ad; }s[2000001]; void build(int i,int l,int r) { s[i].l=l;s[i].r=r; if(l==r) { s[i].v=a[l];return; } build(i*2,l,(l+r)/2); build(i*2+1,(l+r)/2+1,r); s[i].v=s[i*2].v+s[i*2+1].v; } void ask(int i,int ll,int rr) { if(s[i].ad!=0) { s[i].v+=s[i].ad*(s[i].r-s[i].l+1); s[2*i].ad+=s[i].ad; s[2*i+1].ad+=s[i].ad; s[i].ad=0; } if(s[i].l>=ll&&s[i].r<=rr) { sum+=s[i].v; return; } int kk=i*2; if(s[kk].r>=ll)ask(kk,ll,rr); if(s[kk+1].l<=rr)ask(kk+1,ll,rr); } void add(int i,int ll,int rr,int x) { if(s[i].l>=ll&&s[i].r<=rr) { s[i].ad+=x; return; } if(ll>=s[i].l&&rr<=s[i].r)s[i].v+=x*(rr-ll+1); else s[i].v+=x*(min(abs(s[i].r-ll+1),abs(rr-s[i].l+1))); if(s[i].ad!=0) { s[i].v+=(s[i].r-s[i].l+1)*s[i].ad; s[2*i].ad+=s[i].ad; s[2*i+1].ad+=s[i].ad; s[i].ad=0; } int kk=i*2; if(s[kk].r>=ll)add(kk,ll,rr,x); if(s[kk+1].l<=rr)add(kk+1,ll,rr,x); } int main () { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; cin>>q; build(1,1,n); for(int i=1;i<=q;i++) { int k;cin>>k; if(k==1) { int b,c,d; cin>>b>>c>>d; add(1,b,c,d); } if(k==2) { int b,c; cin>>b>>c; sum=0; ask(1,b,c); cout<<sum<<endl; } } }
codevs 1082 线段树练习3
最新推荐文章于 2017-08-22 11:31:00 发布