思路:分块
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
int block, st[N], ed[N], pos[N], sum[N], add[N], a[N],d[N],n,m;
void change()
{
int l, r, k;
cin >> l >> r >> k;
int p = pos[l], q = pos[r];
int ans = 0;
if (p == q)
{
for (int i = l;i <= r;i++)a[i] += k, d[i] = a[i];
sort(d + st[p], d + ed[p] + 1);
}
else
{
for (int i = l;i <= ed[p];i++)
a[i] += k;
for (int i = st[p];i <= ed[p];i++)d[i] = a[i];
sort(d + st[p], d + ed[p] + 1);
for (int i = st[q];i <= r;i++)
a[i] += k;
for (int i = st[q];i <= ed[q];i++)d[i] = a[i];
sort(d + st[q], d + ed[q] + 1);
for (int i = p + 1;i <= q - 1;i++)
{
add[i] += k;
}
}
}
void query()
{
int l, r, k;
cin >> l >> r >> k;
int p = pos[l], q = pos[r];
int ans = 0;
if (p == q)
{
for (int i = l;i <= r;i++)if (a[i] + add[p] >= k)ans++;
}
else
{
for (int i = l;i <= ed[p];i++)if (a[i] + add[p] >= k)ans++;
for (int i = st[q];i <= r;i++)if (a[i] + add[q] >= k)ans++;
for (int i = p + 1;i <= q - 1;i++)
{
int ll = st[i], rr = ed[i];
int mid, res=0;
while (ll <= rr)
{
mid = (ll + rr) / 2;
if (d[mid] + add[i] >= k)rr = mid - 1, res = ed[i]-mid+1;
else ll = mid + 1;
}
ans += res;
}
}
cout << ans << endl;
}
void build()
{
block = sqrt(n);//1
int t = n / block;//2
if (n % block)t++;
for (int i = 1;i <= t;i++)//3
{
st[i] = (i - 1) * block + 1;
ed[i] = i * block;
}
ed[t] = n;
for (int i = 1;i <= n;i++)pos[i] = (i - 1) / block + 1;//4
for (int i = 1;i <= n;i++)d[i] = a[i];//5
for (int i = 1;i <= t;i++)
sort(d + st[i], d + ed[i] + 1);
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n >> m;
for (int i = 1;i <= n;i++)cin >> a[i];
build();
while (m--)
{
char op;
cin >> op;
if (op == 'A')
{
query();
}
else
{
change();
}
}
return 0;
}