支持区间加,区间查询大于等于一个数的分块,WA 求调。T^T
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define ll long long
#define N 1000010
using namespace std;
int n, m, T, tot, p[N], l[N], r[N];
ll a[N], b[N], tag[N];
void build() {
T = pow(n, 0.6);
tot = n / T + (n % T != 0);
for (int i = 1; i <= n; i ++ ) b[i] = a[i];
for (int i = 1; i <= n; i ++ ) p[i] = (i - 1) / T + 1;
for (int i = 1; i <= tot; i ++ ) {
l[i] = (i - 1) * T + 1;
r[i] = i * T;
}
r[tot] = n;
for (int i = 1; i <= tot; i ++ ) sort(b + l[i], b + r[i] + 1);
}
void update(int x, int y, ll c) {
if (p[x] == p[y]) {
for (int i = l[p[x]]; i <= r[p[x]]; i ++ ) {
if (i >= x && i <= y) a[i] += c;
b[i] = a[i];
}
sort(b + l[p[x]], b + r[p[x]] + 1);
} else {
for (int i = p[x] + 1; i < p[y]; i ++ ) tag[i] += c;
for (int i = l[p[x]]; i <= r[p[x]]; i ++ ) {
if (i >= x) a[i] += c;
b[i] = a[i];
}
sort(b + l[p[x]], b + r[p[x]] + 1);
for (int i = l[p[y]]; i <= r[p[y]]; i ++ ) {
if (i <= y) a[i] += c;
b[i] = a[i];
}
sort(b + l[p[y]], b + r[p[y]] + 1);
}
}
int query(int x, int y, ll c) {
int ans = 0;
if (p[x] == p[y]) {
for (int i = x; i <= y; i ++ )
if (a[i] + tag[p[x]] >= c) ans ++ ;
} else {
for (int i = x; i <= r[p[x]]; i ++ )
if (a[i] + tag[p[x]] >= c) ans ++ ;
for (int i = l[p[y]]; i <= y; i ++ )
if (a[i] + tag[p[y]] >= c) ans ++ ;
for (int i = p[x] + 1; i < p[y]; i ++ ) {
int L = l[i], R = r[i];
while (L < R) {
int mid = (L + R) >> 1;
if (b[mid] >= c) R = mid;
else L = mid + 1;
}
ans += r[i] - R + 1;
}
}
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) scanf("%lld", &a[i]);
build();
while (m -- ) {
char op[2];
int l, r; ll c;
scanf("%s%d%d%lld", op, &l, &r, &c);
if (*op == 'M') update(l, r, c);
else printf("%d\n", query(l, r, c));
}
return 0;
}