您的位置:首页 > 编程语言

codevs 1082 线段树练习3

2017-08-14 15:06 281 查看
#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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  此代码美丽