点更新:
const int N=1005;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[N<<2],n;
void Push_up(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void Build(int l,int r,int rt){
if(l==r){sum[rt]=a[l];return ;}
int m=(l+r)>>1;//以rt为根,子区间的接口处
Build(lson);
Build(rson);
Push_up(rt);
}
//点修改A[P]+=C;
void Update(int P,int C,int l,int r,int rt){
if(l==r){sum[rt]+=C;return ;}//到达叶节点,修改叶节点的值
int m=(l+r)>>1;
//根据条件判断往左子树调用还是右子树
if(P<=m)Update(P,C,lson);//P点在左子树就去更新左子树
else Update(P,C,rson);
Push_up(rt);
}
int Query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return sum[rt];
}
int m=(l+r)>>1;
int ans=0;
if(L<=m)ans+=Query(L,R,lson);
if(R>m)ans+=Query(L,R,rson);
return ans;
}
区间更新:
const int N=1005;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[N<<2],add[N<<2],n;
void Push_up(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void Build(int l,int r,int rt){
if(l==r){sum[rt]=a[l];return ;}
int m=(l+r)>>1;//以rt为根,子区间的接口处
Build(lson);
Build(rson);
Push_up(rt);
}
void Push_down(int rt,int ln,int rn){
if(add[rt]){
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=add[rt]*ln;
sum[rt<<1|1]+=add[rt]*rn;
add[rt]=0;
}
}
//区间修改A[l,r]+=C;
void Update(int L,int R,int C,int l,int r,int rt){
if(L<=l&&r<=R){
sum[rt]+=C*(r-l+1);
add[rt]+=C;
return ;
}
int m=(l+r)>>1;
Push_down(rt,m-l+1,r-m);
//根据条件判断往左子树调用还是右子树
if(L<=m)Update(L,R,C,lson);
if(R>m) Update(L,R,C,rson);
Push_up(rt);
}
int Query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return sum[rt];
}
int m=(l+r)>>1;
Push_down(rt,m-l+1,r-m);
int ans=0;
if(L<=m)ans+=Query(L,R,lson);
if(R>m)ans+=Query(L,R,rson);
return ans;
}
注意点和区间更新时update函数的差别~