您的位置:首页 > 其它

线段树模板——Orz SWC学长

2016-05-07 17:47 232 查看
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
const int MAXN= 1000000+50;

LL num[MAXN];

struct meiko
{
LL l,r;
LL sum,add;
}sz[MAXN<<2];

void update(LL p)
{
sz[p].sum=sz[p<<1].sum+sz[(p<<1)+1].sum;
}
void buff(LL p)
{
if(sz[p].add)
{
sz[p<<1].sum+=sz[p].add*(sz[p<<1].r-sz[p<<1].l+1);
sz[p<<1|1].sum+=sz[p].add*(sz[p<<1|1].r-sz[p<<1|1].l+1);
sz[p<<1].add+=sz[p].add;
sz[p<<1|1].add+=sz[p].add;
sz[p].add=0;
}
}

void build(LL l,LL r,LL p)
{
sz[p].l=l;
sz[p].r=r;
if(l==r)
{
sz[p].sum=num[l];
return;
}
LL mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
update(p);
}

void addd(LL p,LL l,LL r,LL jia)
{
if(l<=sz[p].l&&sz[p].r<=r)
{
sz[p].sum+=(sz[p].r-sz[p].l+1)*jia;
sz[p].add+=jia;
return;
}
buff(p);
LL mid=(sz[p].r+sz[p].l)>>1;
if(l<=mid)
addd(p<<1,l,r,jia);
if(r>mid)
addd(p<<1|1,l,r,jia);
update(p);
}

LL ask(LL p,LL l,LL r)
{
LL ans=0;
if(l<=sz[p].l&&sz[p].r<=r )
{
return sz[p].sum;
}
buff(p);

LL mid = (sz[p].l + sz[p].r) >> 1;
if(l <= mid)
{
ans += ask(p<< 1, l, r);
}
if(r > mid)
{
ans += ask(p<< 1 | 1, l, r);
}
return ans;
}

int main()
{
LL n,q;
scanf("%lld%lld",&n,&q);
for(LL i=1;i<=n;i++)
{
scanf("%lld",&num[i]);
}

build(1,n,1);

for(LL i=1;i<=q;i++)
{
char hah;
cin>>hah;
{
if(hah=='Q')
{
LL a,b;
scanf("%lld%lld",&a,&b);
printf("%lld\n",ask(1,a,b));
}
else if(hah=='C')
{
LL a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
addd(1,a,b,c);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: