修改:区间加,区间除
查询:区间最小值,区间和
原题是这道:[雅礼集训 2017 Day1]市场
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5 + 10, inf = 1e18;
int n, q;
int a[maxn];
struct node {
int l, r, ad, val, minn, maxn;
} tr[maxn << 2];
void f(int u, int l, int r, int x) {
tr[u].val += (r - l + 1) * x;
tr[u].minn += x;
tr[u].maxn += x;
tr[u].ad += x;
}
void pushdown(int u) {
if (!tr[u].ad) return;
int mid = tr[u].l + tr[u].r >> 1;
f(u << 1, tr[u].l, mid, tr[u].ad);
f(u << 1 | 1, mid + 1, tr[u].r, tr[u].ad);
tr[u].ad = 0;
}
void pushup(int u) {
tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
tr[u].maxn = max(tr[u << 1].maxn, tr[u << 1 | 1].maxn);
tr[u].val = tr[u << 1].val + tr[u << 1 | 1].val;
}
void build(int u, int l, int r) {
tr[u] = (node) {
l, r, 0, 0, inf, 0
};
if (l == r) {
tr[u].val = tr[u].minn = tr[u].maxn = a[l];
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void add(int u, int l, int r, int x) {
if (tr[u].l >= l && tr[u].r <= r) {
f(u, tr[u].l, tr[u].r, x);
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) add(u << 1, l, r, x);
if (mid < r) add(u << 1 | 1, l, r, x);
pushup(u);
}
int d(int x, int y) {
return floor((double) x / y);
}
void chu(int u, int l, int r, int x) {
int o = d(tr[u].maxn, x) - tr[u].maxn, p = d(tr[u].minn, x) - tr[u].minn;
if (tr[u].l >= l && tr[u].r <= r && o == p) {
f(u, tr[u].l, tr[u].r, o);
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) add(u << 1, l, r, x);
if (mid < r) add(u << 1 | 1, l, r, x);
pushup(u);
}
int querymin(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) return tr[u].minn;
pushdown(u);
int res = inf, mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) res = min(res, querymin(u << 1, l, r));
if (mid < r) res = min(res, querymin(u << 1 | 1, l, r));
return res;
}
int query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) return tr[u].val;
pushdown(u);
int res = 0, mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) res += query(u << 1, l, r);
if (mid < r) res += query(u << 1 | 1, l, r);
return res;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> q;
for (int i = 1; i <= n; ++i) cin >> a[i];
build(1, 1, n);
for (int i = 1, op, x, y, z; i <= q; ++i) {
cin >> op >> x >> y;
x++, y++;// aaa!
if (op == 1) {
cin >> z;
add(1, x, y, z);
} else if (op == 2) {
cin >> z;
chu(1, x, y, z);
} else if (op == 3) cout << querymin(1, x, y) << '\n';
else cout << query(1, x, y) << '\n';
}
}