這是帶上 lazy 標記的線段樹板子
int a[N];
int ls(int p){return p << 1;}
int rs(int p){return p << 1|1;}
class SegmentTree{
public:
int tree[N << 2|1], tag[N << 2 |1];
inline void push_up(int p){
tree[p] = tree[ls(p)] + tree[rs(p)];
}
inline void add(int p, int pl, int pr, int d){
tree[p] += (pr - pl + 1)*d;
tag[p] += d;
}
inline void build(int p, int pl, int pr){
tag[p] = 0;
if(pl == pr){
tree[p] = a[pl];
return ;
}
int mid = (pl + pr) >> 1;
build(ls(p), pl, mid);
build(rs(p), mid + 1, pr);
push_up(p);
}
inline void push_down(int p, int pl, int pr){
if(tag[p]){
int mid = (pl + pr) >> 1;
add(ls(p), pl, mid, tag[p]);
add(rs(p), mid + 1, pr, tag[p]);
tag[p] = 0;
}
}
inline void update(int L, int R, int p, int pl, int pr, int d){
if(L <= pl && pr <= R){
add(p, pl, pr, d);
return ;
}
push_down(p, pl, pr);
int mid = (pl + pr) >> 1;
if(L <= mid){
update(L, R, ls(p), pl, mid, d);
}
if(R >= mid + 1){
update(L, R, rs(p), mid + 1, pr, d);
}
push_up(p);
}
inline int query(int L, int R, int p, int pl, int pr){
if(L <= pl && pr <= R){
return tree[p];
}
int mid = (pl + pr) >> 1;
push_down(p, pl, pr);
int res = 0;
if(L <= mid){
res += query(L, R, ls(p), pl, mid);
}
if(R >= mid + 1){
res += query(L, R, rs(p), mid + 1, pr);
}
return res;
}
};
SegmentTree seg;