#include #include #include using namespace std; const int N = 1e6 + 6; char nc() { static char buf[1000000], *p = buf, *q = buf; return p == q && (q = (p = buf) + fread(buf, 1, 1000000, stdin), p == q) ? EOF : *p++; } int rd() { int res = 0; char c = nc(); while (!isdigit(c)) c = nc(); while (isdigit(c)) res = res * 10 + c - '0', c = nc(); return res; } int t, n, m; int a[N]; int mx[N << 2], se[N << 2], cn[N << 2], tag[N << 2]; long long sum[N << 2]; inline void pushup(int u) { // 向上更新标记 const int ls = u << 1, rs = u << 1 | 1; sum[u] = sum[ls] + sum[rs]; if (mx[ls] == mx[rs]) { mx[u] = mx[rs]; se[u] = max(se[ls], se[rs]); cn[u] = cn[ls] + cn[rs]; } else if (mx[ls] > mx[rs]) { mx[u] = mx[ls]; se[u] = max(se[ls], mx[rs]); cn[u] = cn[ls]; } else { mx[u] = mx[rs]; se[u] = max(mx[ls], se[rs]); cn[u] = cn[rs]; } } inline void pushtag(int u, int tg) { // 单纯地打标记,不暴搜 if (mx[u] <= tg) return; sum[u] += (1ll * tg - mx[u]) * cn[u]; mx[u] = tag[u] = tg; } inline void pushdown(int u) { // 下传标记 if (tag[u] == -1) return; pushtag(u << 1, tag[u]), pushtag(u << 1 | 1, tag[u]); tag[u] = -1; } void build(int u = 1, int l = 1, int r = n) { // 建树 tag[u] = -1; if (l == r) { sum[u] = mx[u] = a[l], se[u] = -1, cn[u] = 1; return; } int mid = (l + r) >> 1; build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); pushup(u); } void modify_min(int L, int R, int v, int u = 1, int l = 1, int r = n) { if (mx[u] <= v) return; if (L <= l && r <= R && se[u] < v) return pushtag(u, v); int mid = (l + r) >> 1; pushdown(u); if (L <= mid) modify_min(L, R, v, u << 1, l, mid); if (mid < R) modify_min(L, R, v, u << 1 | 1, mid + 1, r); pushup(u); } int query_max(int L, int R, int u = 1, int l = 1, int r = n) { // 查询最值 if (L <= l && r <= R) return mx[u]; int mid = (l + r) >> 1, r1 = -1, r2 = -1; pushdown(u); if (L <= mid) r1 = query_max(L, R, u << 1, l, mid); if (mid < R) r2 = query_max(L, R, u << 1 | 1, mid + 1, r); return max(r1, r2); } long long query_sum(int L, int R, int u = 1, int l = 1, int r = n) { // 数值 if (L <= l && r <= R) return sum[u]; int mid = (l + r) >> 1; long long res = 0; pushdown(u); if (L <= mid) res += query_sum(L, R, u << 1, l, mid); if (mid < R) res += query_sum(L, R, u << 1 | 1, mid + 1, r); return res; } void go() { // 根据题意 n = rd(), m = rd(); for (int i = 1; i <= n; i++) a[i] = rd(); build(); for (int i = 1; i <= m; i++) { int op, x, y, z; op = rd(), x = rd(), y = rd(); if (op == 0) z = rd(), modify_min(x, y, z); else if (op == 1) printf("%d\n", query_max(x, y)); else printf("%lld\n", query_sum(x, y)); } } signed main() { t = rd(); while (t--) go(); return 0; }