37 lines
1.2 KiB
C++
37 lines
1.2 KiB
C++
struct Data{
|
|
ll sum, lazy;
|
|
constexpr Data(ll m):sum(m), lazy(){}
|
|
constexpr Data(ll sum, ll lazy):sum(sum), lazy(lazy){}
|
|
};
|
|
Data join(Data A, Data B) {return A.sum+B.sum;}
|
|
using Seg = vector<Data>;
|
|
|
|
void init(Seg& seg, int i, int s, int e, ll *A) {
|
|
if(s == e) {seg[i] = A[s]; return;}
|
|
int mid = (s+e)>>1;
|
|
init(seg, i*2, s, mid, A); init(seg, i*2+1, mid+1, e, A);
|
|
seg[i] = join(seg[i*2], seg[i*2+1]);
|
|
}
|
|
void prop(Seg& seg, int i, int s, int e) {
|
|
seg[i].sum += seg[i].lazy * (e-s+1);
|
|
if(s != e) for(auto t:{i*2, i*2+1}) seg[t].lazy += seg[i].lazy;
|
|
seg[i].lazy = 0;
|
|
}
|
|
|
|
void update(Seg& seg, int i, int s, int e, int a, int b, ll v) {
|
|
prop(seg, i, s, e);
|
|
if(e<a||b<s) return;
|
|
if(a<=s&&e<=b) {seg[i].lazy+=v; prop(seg, i, s, e); return;}
|
|
int mid = (s+e)>>1;
|
|
update(seg, i*2, s, mid, a, b, v); update(seg, i*2+1, mid+1, e, a, b, v);
|
|
seg[i] = join(seg[i*2], seg[i*2+1]);
|
|
}
|
|
|
|
ll query(Seg& seg, int i, int s, int e, int a, int b) {
|
|
prop(seg, i, s, e);
|
|
if(e<a||b<s) return 0;
|
|
if(a<=s&&e<=b) return seg[i].sum;
|
|
int mid = (s+e)>>1;
|
|
return query(seg, i*2, s, mid, a, b) + query(seg, i*2+1, mid+1, e, a, b);
|
|
}
|