修改的时候要pushdown 查询的时候也要下放标记
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll maxn=100000+10;
ll tree[maxn<<2],tag[maxn<<2];
int a[maxn],x,y,val;
char s[10];
void pushdown(int node,int len_L,int len_R)
{
if(tag[node])
{
tag[node<<1]+=tag[node];
tag[node<<1|1]+=tag[node];
tree[node<<1]+=tag[node]*len_L;
tree[node<<1|1]+=tag[node]*len_R;
tag[node]=0;
}
}
void creat(int node,int L,int R)
{
if(L==R)
{
tree[node]=a[L];
return;
}
else
{
int mid=(L+R)>>1;
creat(node<<1,L,mid);
creat(node<<1|1,mid+1,R);
tree[node]=tree[node<<1|1]+tree[node<<1];
}
}
ll query(int node,int L,int R,int start,int end) // L, R 为查询区间
{
if(start>R||end<L)
{
return 0;
}
if(start>=L&&end<=R)
{
return tree[node];
}
else
{
int mid=(start+end)>>1;
pushdown(node,mid-start+1,end-mid);
ll lans=0;
ll rans=0;
if(mid>=L)
lans=query(node<<1,L,R,start,mid);
if(mid+1<=R)
rans=query(node<<1|1,L,R,mid+1,end);
return lans+rans;
}
}
void update(int node,int start,int end,int L,int R,int val)
{
if(start>R||end<L)
return;
if(start>=L&&end<=R)
{
tree[node]+=val*(end-start+1);
tag[node]+=val;
return ;
}
else
{
int mid=(start+end)>>1;
pushdown(node,mid-start+1,end-mid);
update(node<<1,start,mid,L,R,val);
update(node<<1|1,mid+1,end,L,R,val);
tree[node]=tree[node<<1]+tree[node<<1|1];
}
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
creat(1,1,n);
for(int i=0;i<m;i++)
{
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%d %d",&x,&y);
printf("%lld\n",query(1,x,y,1,n));
}
if(s[0]=='C')
{
scanf("%d %d %d",&x,&y,&val);
update(1,1,n,x,y,val);
}
}
return 0;
}
来源:https://blog.csdn.net/qq_44115065/article/details/102755015