2021更新版,保姆级教程
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int a[55555];
int f[205555],laz[205555];
int n;
int t;
void _build(int l,int r,int now)//建树
{
if(l==r)
{
f[now]=a[l];
return;
}
int mid=(l+r)>>1;//>>1 右移一位 相当于除以2 速度比除以二稍快
_build(l,mid,now<<1);//<< 1左移一位 相当于乘以2
_build(mid+1,r,now<<1|1);
f[now]=f[now<<1]+f[now<<1|1];//<<1|1 一个数乘以2之后二进制最后一位必定是0 0|1=1 相当于乘以二再加一
}
//更新子节点区间值
void pushdown(int l,int r,int now)
{
int mid=(l+r)>>1;
f[now<<1]+=(mid-l+1)*laz[now];
laz[now<<1]+=laz[now];
f[now<<1|1]+=(r-mid)*laz[now];
laz[now<<1|1]+=laz[now];
laz[now]=0;
return;
}
int _que(int l,int r,int ll,int rr,int now)//询问区间
{
if(ll==l&&rr==r)
{
return f[now];
}
if(laz[now]!=0) pushdown(l,r,now);
int mid=(l+r)>>1;
if(ll>mid)return _que(mid+1,r,ll,rr,now<<1|1);
else if(rr<=mid)return _que(l,mid,ll,rr,now<<1);
else return _que(l,mid,ll,mid,now<<1)+_que(mid+1,r,mid+1,rr,now<<1|1);
}
void _add(int l,int r,int a,int x,int now)//单节点更新
{
if(l==a&&r==a)
{
f[now]+=x;
return;
}
int mid=(l+r)>>1;
if(a<=mid) _add(l,mid,a,x,now<<1);
else _add(mid+1,r,a,x,now<<1|1);
f[now]=f[now<<1]+f[now<<1|1];
}
void _sub(int l,int r,int a,int x,int now)//单节点更新
{
if(l==a&&r==a)
{
f[now]-=x;
return;
}
int mid=(l+r)>>1;
if(a<=mid) _sub(l,mid,a,x,now<<1);
else _sub(mid+1,r,a,x,now<<1|1);
f[now]=f[now<<1]+f[now<<1|1];
}
//区间更新
void update(int l,int r,int ll,int rr,int now,int c)
{
if(l==ll&&r==rr)
{
f[now]+=c*(r-l+1);
laz[now]+=c;
return;
}
if(laz[now]!=0) pushdown(l,r,now);
int mid=(l+r)>>1;
if(rr<=mid) update(l,mid,ll,rr,now<<1,c);
else if(ll>mid) update(mid+1,r,ll,rr,now<<1|1,c);
else {
update(l,mid,ll,mid,now<<1,c);
update(mid+1,r,mid+1,rr,now<<1|1,c);
}
f[now]=f[now<<1]+f[now<<1|1];
}
int main()
{
scanf("%d",&t);
int k=0;
while(t--)
{
k++;
memset(laz,0,sizeof(laz));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
_build(1,n,1);
char s[10];
printf("Case %d:\n",k);
while(~scanf("%s",s))
{
if(s[0]=='E')
break;
else if(s[0]=='Q')
{
int a,b;
scanf("%d%d",&a,&b);
int ans=_que(1,n,a,b,1);
printf("%d\n",ans);
}
else if(s[0]=='A')
{
int a,b;
scanf("%d%d",&a,&b);
_add(1,n,a,b,1);
}
else if(s[0]=='S')
{
int a,b;
scanf("%d%d",&a,&b);
_sub(1,n,a,b,1);
}
else if(s[0]=='U')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
update(1,n,a,b,1,c);
}
}
}
return 0;
}