本人真的是金鱼脑了。。。学过的算法立马忘。。真的是。。
今天复习一下线段树。
#define maxn 200005
int sum[maxn<<2],add[maxn<<2];
int A[maxn],n;
void pushup(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;
build(l,m,rt<<1);
bulid(m+1,r,rt<<1|1);
pushup(rt);
}
void update(int L,int c,int l,int r,int rt){//rt表示当前节点,A[L]+=c
if(l==r){
sum[rt]+=c;
return ;
}
int m=(l+r)>>1;
if(L<=m) update(L,c,l,m,rt<<1);
if(R>m) update(L,c,m+1,r,rt<<1|1);
pushup(rt);
}
void pushdown(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;
}
}
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;
pushdown(rt,m-l+1,r-m);
if(L<=m) Update(L,R,c,l,m,rt<<1);
if(R>m) Update(L,R,c,m+1,r,rt<<1|1);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){//L,R为操作区间
if(L<=l&&r<=R){
return sum[rt];
}
int m=(l+r)>>1;
pushdown(rt,m-l+1,r-m);
int ans=0;
if(L<=m) ans+=query(L,R,l,m,rt<<1);
if(R>m) ans+=query(L,R,m+1,r,rt<<1|1);
return ans;
}