稍微解释一下lazy变量的作用:
为了避免对无需查询的线段树节点进行更新(浪费了没有必要的时间),我们可以建立一个lazy变量,来暂时储存一个节点对之后节点的增量
(在询问到这个节点以后,当我们发现他并不是我们查询的确切空间,再使用lazy对他的子节点(子节点具有更精确的范围)进行更新)
#include
#define ll long long
#define maxn 50500
using namespace std;
ll a[maxn];
struct tree{
int l;
int r;
int val;
int lazy;
}tree[4*maxn];
void pushdown(int root)
{
tree[root*2].val+=tree[root].lazy*(tree[root*2].r-tree[root*2].l+1);
tree[root*2+1].val+=tree[root].lazy*(tree[root*2+1].r-tree[root*2+1].l+1);
tree[root*2].lazy+=tree[root].lazy;
tree[root*2+1].lazy+=tree[root].lazy;
tree[root].lazy=0;
}
void build(int root,int left,int right)
{
int mid=(left+right)>>1;
tree[root].l=left;
tree[root].r=right;
tree[root].val=0;
tree[root].lazy=0;
if(left==right)
{
tree[root].val=a[left];
return;
}
build(root*2,left,mid);
build(root*2+1,mid+1,right);
tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
int quiry(int root,int left,int right)
{
int mid=(tree[root].l+tree[root].r)>>1;
if(tree[root].l>=left&&tree[root].r<=right)
return tree[root].val;
if(tree[root].lazy)
pushdown(root);
if(right<=mid)
return quiry(root*2,left,right);
if(left>mid)
return quiry(root*2+1,left,right);
return quiry(root*2,left,mid)+quiry(root*2+1,mid+1,right);
}
void update(int root,int left,int right,int val)
{
if(left<=tree[root].l&&right>=tree[root].r)
{
tree[root].val+=val*(right-left+1);
tree[root].lazy+=val;
return ;
}
pushdown(root);
int mid=(tree[root].l+tree[root].r)>>1;
if(right<=mid)
update(root*2,left,right,val);
else if(left>mid)
update(root*2+1,left,right,val);
else
{
update(root*2,left,mid,val);
update(root*2+1,mid+1,right,val);
}
tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=t;i++)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
printf("Case %d:\n",i);
while(1)
{
char s[15];
scanf("%s",s);
if(s[0]=='Q')
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",quiry(1,a,b));
}
else if(s[0]=='A')
{
int a,b;
scanf("%d%d",&a,&b);
update(1,a,a,b);
}
else if(s[0]=='S')
{
int a,b;
scanf("%d%d",&a,&b);
update(1,a,a,-b);
}
else
{
break;
}
}
}
}