#include using namespace std; const int MX_N = 1000000, MX_Q = 100000, TREAP_SIZE = MX_Q * 18 * 20 * 2; struct TreapNode { int val, sz, lSon, rSon, prior; } t[TREAP_SIZE]; int tw; int newNode(int val, int lSon = 0, int rSon = 0) { int v = tw++; assert(v < TREAP_SIZE); t[v].val = val; t[v].lSon = lSon; t[v].rSon = rSon; t[v].prior = rand(); t[v].sz = t[t[v].lSon].sz + t[t[v].rSon].sz + 1; return v; } int merge(int u, int v) { if (u == 0 || v == 0) return u + v; if (t[u].prior > t[v].prior) { return newNode(t[u].val, t[u].lSon, merge(t[u].rSon, v)); } else { return newNode(t[v].val, merge(u, t[v].lSon), t[v].rSon); } } int cut(int v, int threshold) { if (v == 0) return 0; if (t[v].val > threshold) { return newNode(t[v].val, cut(t[v].lSon, threshold), t[v].rSon); } else { return cut(t[v].rSon, threshold); } } int getLast(int v) { while (t[v].rSon != 0) v = t[v].rSon; return t[v].val; } int combine(int u, int v) { if (u == 0 || v == 0) return u + v; v = cut(v, getLast(u)); return merge(u, v); } struct Query { bool add; int i, x, l, r; Query(int i, int x) : add(true), i(i), x(x) { } Query(int i, int l, int r) : add(false), i(i), l(l), r(r) { } }; vector q; void solve(vector>& vec, int l, int r) { if (r - l == 1) { if (q[l].add == false) { int ans = 0; for (auto& x : vec) if (x.first >= q[l].i) ans = combine(ans, x.second); ans = cut(ans, q[l].l - 1); int total = t[ans].sz; ans = cut(ans, q[l].r - 1); printf("%d\n", total - max(t[ans].sz - 1, 0)); } return; } set special; for (int i = l; i < r; i++) special.insert(q[i].i); vector> compressed; int last = 0, lastPos = 0; for (auto& x : vec) { if (special.count(x.first) == 1) { if (last != 0) compressed.emplace_back(lastPos, last); compressed.push_back(x); last = 0; lastPos = x.first + 1; } else last = combine(last, x.second); } if (last != 0) compressed.emplace_back(lastPos, last); int c = (l + r) / 2; solve(compressed, l, c); static size_t positions[MX_N]; for (size_t i = 0; i < compressed.size(); i++) { positions[compressed[i].first] = i; } for (int i = l; i < c; i++) if (q[i].add) { int& v = compressed[positions[q[i].i]].second; v = newNode(t[v].val + q[i].x); } solve(compressed, c, r); } int a[MX_N]; int main() { int T; ignore = scanf("%d", &T); while (T--) { tw = 1; q.clear(); int n, m; ignore = scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) ignore = scanf("%d", a + i); for (int i = 0; i < m; i++) { char c; ignore = scanf(" %c", &c); if (c == '+') { int id, x; ignore = scanf("%d %d", &id, &x); q.emplace_back(id - 1, x); } else { int id, l, r; ignore = scanf("%d %d %d", &id, &l, &r); q.emplace_back(id - 1, l, r); } } vector> vec; for (int i = 0; i < n; i++) vec.emplace_back(i, newNode(a[i])); solve(vec, 0, m); } return 0; }