codevs 1082 线段树练习3

来源:互联网 发布:淘宝夜鹰 编辑:程序博客网 时间:2024/06/05 20:53
#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;}}}
原创粉丝点击