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 108 109 110 111 112 113 114 115 116 117
| #include <bits/stdc++.h> using namespace std; typedef long long ll; #define lson(u) node[u].l #define rson(u) node[u].r #define tag(u) node[u].tag #define maxx(u) node[u].maxx #define minn(u) node[u].minn #define sum(u) node[u].sum
const int maxn = 100005; const int inf = 0x3f3f3f3f;
struct Node { int l, r, tag, minn, maxx; ll sum; }node[maxn << 1]; int cnt;
int N, Q, R; int a[maxn];
inline void pushdown(int u, int l, int r) { if (tag(u)) { int mid = (l + r) >> 1; int llen = mid - l + 1, rlen = r - mid; sum(lson(u)) += 1ll * tag(u) * llen, sum(rson(u)) += 1ll * tag(u) * rlen; minn(lson(u)) += tag(u), minn(rson(u)) += tag(u); maxx(lson(u)) += tag(u), maxx(rson(u)) += tag(u); tag(lson(u)) += tag(u), tag(rson(u)) += tag(u); tag(u) = 0; } }
inline void pushup(int u) { sum(u) = sum(lson(u)) + sum(rson(u)); minn(u) = min(minn(lson(u)), minn(rson(u))); maxx(u) = max(maxx(lson(u)), maxx(rson(u))); }
void build(int& u, int l, int r) { u = ++cnt; sum(u) = 0, minn(u) = inf, maxx(u) = -inf; if (l == r) { sum(u) = minn(u) = maxx(u) = a[l]; return; } int mid = (l + r) >> 1; build(lson(u), l, mid), build(rson(u), mid + 1, r); pushup(u); }
void modify_range_add(int u, int l, int r, int ql, int qr, int val) { if (ql <= l && r <= qr) { tag(u) += val; sum(u) += 1ll * val * (r - l + 1); minn(u) += val; maxx(u) += val; return; } pushdown(u, l, r); int mid = (l + r) >> 1; if (ql <= mid) modify_range_add(lson(u), l, mid, ql, qr, val); if (mid < qr) modify_range_add(rson(u), mid + 1, r, ql, qr, val); pushup(u); }
void modify_range_divide(int u, int l, int r, int ql, int qr, int val) { if (ql <= l && r <= qr) { int dmin = minn(u) - floor(1.0 * minn(u) / val), dmax = maxx(u) - floor(1.0 * maxx(u) / val); if (dmin == dmax) { tag(u) -= dmin; sum(u) -= 1ll * dmin * (r - l + 1); minn(u) -= dmin; maxx(u) -= dmin; return; } } pushdown(u, l, r); int mid = (l + r) >> 1; if (ql <= mid) modify_range_divide(lson(u), l, mid, ql, qr, val); if (mid < qr) modify_range_divide(rson(u), mid + 1, r, ql, qr, val); pushup(u); }
int query_range_min(int u, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) return minn(u); pushdown(u, l, r); int mid = (l + r) >> 1, ret = inf; if (ql <= mid) ret = min(ret, query_range_min(lson(u), l, mid, ql, qr)); if (mid < qr) ret = min(ret, query_range_min(rson(u), mid + 1, r, ql, qr)); return ret; }
ll query_range_sum(int u, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) return sum(u); pushdown(u, l, r); int mid = (l + r) >> 1; ll ret = 0; if (ql <= mid) ret += query_range_sum(lson(u), l, mid, ql, qr); if (mid < qr) ret += query_range_sum(rson(u), mid + 1, r, ql, qr); return ret; }
int main() { scanf("%d%d", &N, &Q); for (int i = 0; i < N; ++i) scanf("%d", &a[i]); build(R, 0, N - 1); for (int i = 1; i <= Q; ++i) { int op, l, r, x; scanf("%d%d%d", &op, &l, &r); if (op == 1) scanf("%d", &x), modify_range_add(R, 0, N - 1, l, r, x); else if (op == 2) scanf("%d", &x), modify_range_divide(R, 0, N - 1, l, r, x); else if (op == 3) printf("%d\n", query_range_min(R, 0, N - 1, l, r)); else printf("%lld\n", query_range_sum(R, 0, N - 1, l, r)); } return 0; }
|