#include <bits/stdc++.h>
#define sc(x) scanf("%lld", &(x))
#define pr(x) printf("%lld\n", (x))
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
ll a[N], tree[N << 2], lazy[N << 2];
ll n, m, op, x, y, k;
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid (l + r >> 1)
void bulid(ll p = 1, ll l = 1, ll r = n) {
    lazy[p] = 0;
    if (l == r) {
        tree[p] = a[l];
        return;
    }
    bulid(ls, l, mid);
    bulid(rs, mid + 1, r);
    tree[p] = tree[ls] + tree[rs];
}
inline void PushDown(ll p, ll tot) {
    lazy[ls] += lazy[p];
    lazy[rs] += lazy[p];
    tree[ls] += lazy[p] * (tot - tot / 2);
    tree[rs] += lazy[p] * (tot / 2);
    lazy[p] = 0;
}
void add(ll x, ll y, ll val, ll p = 1, ll l = 1, ll r = n) {
    if (x <= l && r <= y) {  //当前区间可被所求区间覆盖
        lazy[p] += val;
        tree[p] += val * ((ll)(r - l + 1));
        return;
    }
    PushDown(p, r - l + 1);
    if (x <= mid) add(x, y, val, ls, l, mid);
    if (y > mid) add(x, y, val, rs, mid + 1, r);
    tree[p] = tree[ls] + tree[rs];
}
ll query(ll x, ll y, ll p = 1, ll l = 1, ll r = n) {
    if (x <= l && r <= y) return tree[p];
    ll res = 0;
    if (lazy[p]) PushDown(p, r - l + 1);
    if (x <= mid) res += query(x, y, ls, l, mid);
    if (y > mid) res += query(x, y, rs, mid + 1, r);
    return res;
}
int main() {
    sc(n), sc(m);
    for (int i = 1; i <= n; ++i) sc(a[i]);
    bulid();
    while (m--) {
        sc(op);
        if (op & 1) {
            sc(x), sc(y), sc(k);
            add(x, y, k);
        } else {
            sc(x), sc(y);
            pr(query(x, y));
        }
    }
    return 0;
}

改成区间查询最小值

#include <bits/stdc++.h>
#define sc(x) scanf("%lld", &(x))
#define pr(x) printf("%lld\n", (x))
//线段树维护区间最小值 区间加
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
ll a[N], tree[N << 2], lazy[N << 2], n;
ll m, op, x, y, k;
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid (l + r >> 1)
void bulid(ll p = 1, ll l = 1, ll r = n) {
    lazy[p] = 0;
    if (l == r) {
        tree[p] = a[l];
        return;
    }
    bulid(ls, l, mid);
    bulid(rs, mid + 1, r);
    tree[p] = min(tree[ls], tree[rs]);
}
inline void PushDown(ll p) {
    if (lazy[p]) {
        lazy[ls] += lazy[p];
        lazy[rs] += lazy[p];
        tree[ls] += lazy[p];
        tree[rs] += lazy[p];
        lazy[p] = 0;
    }
}
void add(int x, int y, ll val = 1, int p = 1, int l = 1, int r = n) {
    if (x <= l && r <= y) {  //当前区间可被所求区间覆盖
        lazy[p] += val;
        tree[p] += val;
        return;
    }
    PushDown(p);
    if (x <= mid) add(x, y, val, ls, l, mid);
    if (y > mid) add(x, y, val, rs, mid + 1, r);
    tree[p] = min(tree[ls], tree[rs]);
}
ll query(ll x, ll y, int p = 1, int l = 1, int r = n) {
    if (x <= l && r <= y) return tree[p];
    if (lazy[p]) PushDown(p);
    if (y <= mid) return query(x, y, ls, l, mid);
    if (x > mid) return query(x, y, rs, mid + 1, r);
    return min(query(x, y, ls, l, mid), query(x, y, rs, mid + 1, r));
}
int main() {
    sc(n), sc(m);
    // for (int i = 1; i <= n; ++i) sc(a[i]);
    bulid();
    while (m--) {
        sc(op);
        if (op & 1) {
            sc(x), sc(y), sc(k);
            add(x, y, k);
        } else {
            sc(x), sc(y);
            pr(query(x, y));
        }
    }
    return 0;
}