题目链接:Gorgeous Sequence
/**
* 维护区间最大值,及其个数,再记录一个次大值。
* 感谢jry_2..的论文
*
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
void scan() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
}
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 7;
ll a[maxn], st[maxn << 2], cha[maxn << 2];
ll mx[maxn << 2], se[maxn << 2], num[maxn << 2];
void push_up(int o) {
st[o] = st[o << 1] + st[o << 1 | 1];
mx[o] = max(mx[o << 1], mx[o << 1 | 1]);
se[o] = max(se[o << 1], se[o << 1 | 1]);
if (mx[o << 1] != mx[o << 1 | 1]) se[o] = max(se[o], min(mx[o << 1], mx[o << 1 | 1]));
num[o] = 0;
if (mx[o] == mx[o << 1]) num[o] += num[o << 1];
if (mx[o] == mx[o << 1 | 1]) num[o] += num[o << 1 | 1];
}
void push_tag(int o, int c) {
if (c >= mx[o]) return;
st[o] += (c - mx[o]) * num[o];//
mx[o] = c;
}
void push_down(int o) {
push_tag(o << 1, mx[o]);
push_tag(o << 1 | 1, mx[o]);
}
void build(int o, int l, int r) {
if (l == r) {
st[o] = mx[o] = a[l];
num[o] = 1;
se[o] = -1;
return;
}
int mid = l + ((r - l >> 1));
build(o << 1, l, mid);
build(o << 1 | 1, mid + 1, r);
push_up(o);
}
void update(int o, int l, int r, int ql, int qr, int c) {
if (c >= mx[o]) return;
if (ql <= l && qr >= r && c > se[o]) {
push_tag(o, c);//c比次小的大,比最大的小。贡献的变化。
return;
}
push_down(o);
int mid = l + ((r - l) >> 1);
if (ql <= mid) update(o << 1, l, mid, ql, qr, c);
if (qr >= mid + 1) update(o << 1 | 1, mid + 1, r, ql, qr, c);
push_up(o);//上推标记。
}
ll query_max(int o, int l, int r, int ql, int qr) {//最大值
if (ql <= l && qr >= r) {
return mx[o];
}
int mid = l + ((r - l) >> 1);
push_down(o);
ll Maxx = 0;
if (ql <= mid) Maxx = query_max(o << 1, l, mid, ql, qr);
if (qr >= mid + 1) Maxx = max(Maxx, query_max(o << 1 | 1, mid + 1, r, ql, qr));
return Maxx;
}
ll query_sum(int o, int l, int r, int ql, int qr) {//区间和
if (ql <= l && qr >= r) return st[o];
push_down(o);
int mid = l + ((r - l) >> 1);
ll ans = 0;
if (ql <= mid) ans += query_sum(o << 1, l, mid, ql, qr);
if (qr >= mid + 1) ans += query_sum(o << 1 | 1, mid + 1, r, ql, qr);
return ans;
}
void solve(int T) {
int n, Q;
cin >> n >> Q;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
while (Q--) {
int op, l, r;
cin >> op >> l >> r;
if (op == 0) {
int c;
cin >> c;
update(1, 1, n, l, r, c);
} else if (op == 1) {
cout << query_max(1, 1, n, l, r) << endl;
} else cout << query_sum(1, 1, n, l, r) << endl;
}
}
int main() {
// scan();
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
for (int i = 1; i <= T; i++) solve(T);
return 0;
}