线段树(1)
线段树(1)
最基础的模板:
#define ls(x) x<<1
#define rs(x) x<<1|1
ll tree[N<<2],tag[N<<2];
ll a[N];
void up(ll p){
tree[p] = tree[ls(p)]+tree[rs(p)];
}
//建树
void build(ll p,ll pl,ll pr){
if(pl == pr) {
tree[p] = a[pl];
return;
}
ll mid = (pl+pr)>>1;
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
up(p);
}
void add(ll p,ll pl,ll pr,ll d){
tag[p] += d;
tree[p] += d*(pr-pl+1);
}
void push_down(ll p,ll pl,ll pr){
if(tag[p]){
ll mid = (pl+pr)>>1;
add(ls(p),pl,mid,tag[p]);
add(rs(p),mid+1,pr,tag[p]);
tag[p] = 0;
}
}
void update(ll L,ll R,ll p,ll pl,ll pr,ll d){
if(L <= pl && pr <= R){
add(p,pl,pr,d);
return;
}
push_down(p,pl,pr);
ll mid = (pl+pr)>>1;
if(L <= mid) update(L,R,p,pl,mid,d);
if(mid < R) update(L,R,p,mid+1,d);
up(p,pl,pr);
}
ll query(ll L,ll R,ll p,ll pl,ll pr){
if(L <= pl && pr <= R){
return tree[p];
}
push_down(p,pl,pr);
ll mid = (pl+pr)>>1;
ll res = 0;
if(L <= mid) res += query(L,R,ls(p),pl,mid);
if(mid < R) res += query(L,R,rs(p),mid+1,R);
return res;
}