1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| struct SegTree{ int n; vector<ll> a; vector<ll> add, mi; vector<int> cnt;
#define lp (p << 1) #define rp (p << 1 | 1) #define lk (mid - l + 1) #define rk (r - mid) void init(int n_){ n = n_; cnt = vector<int>(n+1 << 2, -1); a = add = vector<ll>(n+1 << 2); mi = vector<ll>(n+1 << 2, inf); build(1, 0, n); } void init(int n_, auto& a_){ n = n_; a = a_; cnt = vector<int>(n+1 << 2, -1); add = vector<ll>(n+1 << 2); mi = vector<ll>(n+1 << 2, inf); build(1, 0, n); }
void lazy(int p, int k, ll v){ mi[p] += v; add[p] += v; } void pull(int p){ mi[p] = min(mi[lp], mi[rp]); if(mi[lp] < mi[rp]) cnt[p] = cnt[lp]; if(mi[lp] > mi[rp]) cnt[p] = cnt[rp]; if(mi[lp] == mi[rp]) cnt[p] = cnt[lp] + cnt[rp]; } void push(int p, int l, int r){ if(add[p] == 0) return; int mid = l + r >> 1; lazy(lp, lk, add[p]); lazy(rp, rk, add[p]); add[p] = 0; } void build(int p, int l, int r){ if(l == r){ mi[p] = a[l]; cnt[p] = 1; return; }
int mid = l + r >> 1; build(lp, l, mid); build(rp, mid+1, r); pull(p); }
void update(int p, int l, int r, int x, ll v){ if(l == r){ mi[p] = v; return; } int mid = l + r >> 1; push(p, l, r); if(x <= mid) update(lp, l, mid, x, v); else update(rp, mid+1, r, x, v); pull(p); } void update(int p, int l, int r, int x, int y, ll v){ if(x <= l && r <= y){ lazy(p, r - l + 1, v); return; }
int mid = l + r >> 1; push(p, l, r); if(x <= mid) update(lp, l, mid, x, y, v); if(y >= mid + 1) update(rp, mid + 1, r, x, y, v); pull(p); } pair<ll, int> query(int p, int l, int r, int x, int y){ if(x <= l && r <= y) return {mi[p], cnt[p]}; int mid = l + r >> 1; push(p, l, r);
ll mil = inf, mir = inf; int cl = 0, cr = 0; if(x <= mid){ auto [t1, t2] = query(lp, l, mid, x, y); mil = t1; cl = t2; } if(y >= mid + 1){ auto[t1, t2] = query(rp, mid+1, r, x, y); mir = t1; cr = t2; }
if(mil < mir) return {mil, cl}; if(mil > mir) return {mir, cr}; return {mil, cl + cr}; }
void update(int X, ll V){ update(1, 0, n, X, V); } void update(int L, int R, ll V){ update(1, 0, n, L, R, V); } pair<ll, int> query(int L, int R){ return query(1, 0, n, L, R); } };
|