写了俩小时。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define deb(n) cout << #n << "=" << n << " "
#define debug(n) cout << #n << "=" << n << endl
#define div() cout << "_______________" << endl
const int N = 2e5 + 10;
int n, q;
int A[N];
struct type {
int l, r, minv, sum, cnt;
int add, mul;
}tree1[N * 4], tree2[N * 4];
void pushup(int rt) {
int l = tree1[rt].l, r = tree1[rt].r;
if (l != r) {
l = rt * 2, r = rt * 2 + 1;
tree1[rt].sum = tree1[l].sum + tree1[r].sum;
tree1[rt].cnt = tree1[l].cnt + tree1[r].cnt;
tree1[rt].minv = min(tree1[l].minv, tree1[r].minv);
tree2[rt].sum = tree2[l].sum + tree2[r].sum;
tree2[rt].cnt = tree2[l].cnt + tree2[r].cnt;
tree2[rt].minv = min(tree2[l].minv, tree2[r].minv);
}
}
void pushdown(int rt) {
int l = tree1[rt].l, r = tree1[rt].r;
if (l != r) {
l = rt * 2, r = rt * 2 + 1;
if (tree1[rt].add) {
tree1[l].sum += tree1[l].cnt * tree1[rt].add;
tree1[r].sum += tree1[r].cnt * tree1[rt].add;
tree1[l].add += tree1[rt].add;
tree1[r].add += tree1[rt].add;
tree1[l].minv += tree1[rt].add;
tree1[r].minv += tree1[rt].add;
tree1[rt].add = 0;
}
if (tree2[rt].mul != 1) {
tree2[l].sum *= tree2[rt].mul;
tree2[r].sum *= tree2[rt].mul;
tree2[l].mul *= tree2[rt].mul, tree2[l].add *= tree2[rt].mul;
tree2[r].mul *= tree2[rt].mul, tree2[r].add *= tree2[rt].mul;
tree2[rt].mul = 1;
}
if (tree2[rt].add) {
tree2[l].sum += tree2[l].cnt * tree2[rt].add;
tree2[r].sum += tree2[r].cnt * tree2[rt].add;
tree2[l].add += tree2[rt].add;
tree2[r].add += tree2[rt].add;
tree2[rt].add = 0;
}
}
}
void build(int l, int r, int rt) {
tree1[rt] = { l, r, 0, 0, 0, 0, 1 };
tree2[rt] = { l, r, 0, 0, 0, 0, 1 };
if (l == r) {
tree1[rt].sum = tree1[rt].minv = A[l], tree1[rt].cnt = 1, tree1[rt].add = 0, tree1[rt].mul = 1;
tree2[rt].sum = tree2[rt].minv = 0, tree2[rt].cnt = 0, tree2[rt].add = 0, tree2[rt].mul = 1;
return;
}
int mid = (l + r) / 2;
build(l, mid, rt * 2);
build(mid + 1, r, rt * 2 + 1);
pushup(rt);
}
void update1(int l, int r, int rt, int x) {
if (tree1[rt].l >= l && tree1[rt].r <= r) {
tree1[rt].sum += x * tree1[rt].cnt, tree1[rt].minv += x;
tree1[rt].add += x;
tree2[rt].sum = -tree2[rt].sum - x * tree2[rt].cnt;
tree2[rt].add *= -1, tree2[rt].mul *= -1, tree2[rt].add -= x;
return;
}
pushdown(rt);
int mid = (tree1[rt].l + tree1[rt].r) / 2;
if (l <= mid) update1(l, r, rt * 2, x);
if (r >= mid + 1) update1(l, r, rt * 2 + 1, x);
pushup(rt);
}
void update2(int l, int r, int rt, int x) {
if (tree1[rt].l == tree1[rt].r) {
tree2[rt].cnt = 1, tree2[rt].sum = tree1[rt].sum;
tree1[rt].cnt = 0, tree1[rt].minv = 1e18, tree1[rt].sum = 0;
return;
}
pushdown(rt);
int mid = (tree1[rt].l + tree1[rt].r) / 2;
if (tree1[rt * 2].minv < x) update2(l, r, rt * 2, x);
if (tree1[rt * 2 + 1].minv < x) update2(l, r, rt * 2 + 1, x);
pushup(rt);
}
int getsum(int l, int r, int rt) {
if (tree1[rt].l >= l && tree1[rt].r <= r) return tree1[rt].sum + tree2[rt].sum;
pushdown(rt);
int mid = (tree1[rt].l + tree1[rt].r) / 2, sum = 0;
if (l <= mid) sum += getsum(l, r, rt * 2);
if (r >= mid + 1) sum += getsum(l, r, rt * 2 + 1);
return sum;
}
void oper() {
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> A[i];
build(1, n, 1);
for (int tt = 1; tt <= q; tt++) {
int op; cin >> op;
if (op == 1) {
int l, r, x; cin >> l >> r >> x;
if (tree1[1].minv < x) update2(l, r, 1, x);
update1(l, r, 1, -x);
}
else if (op == 2) {
int l, r; cin >> l >> r;
cout << getsum(l, r, 1) << endl;
}
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1; cin >> t;
while (t--) oper();
return 0;
}