写分块的时候一定要注意什么时候用l, r 什么时候用bel[x],bel[y],一不注意就容易出错
// Decline is inevitable,
// Romance will last forever.
#include <bits/stdc++.h>
using namespace std;
#define mst(a, x) memset(a, x, sizeof(a))
#define INF 0x3f3f3f3f
//#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
//#define int long long
const int maxn = 1e6 + 10;
const int maxm = 1e3 + 10;
const int P = 1e9 + 7;
int n, sq;
int start[maxn], ed[maxn]; //start[i]表示第i个数所在的块的最左侧的点,ed表示最右侧的点
int size[maxm], bel[maxn]; //size[i]表示第i块的大小 bel[i]表示第i个数所在的块是第几块
int a[maxn], sum[maxm], m; //a[] 原始数组 sum[i] 第i块的和 维护第i块的信息
int mark[maxm]; //mark[i]表示第i块的每个数的值变化 类似delta偏移量
void init(int n) {
sq = sqrt(n); //每根号n个数一块,一共sq块
for(int i = 1; i <= sq; i++) { //求出每块最左和最右侧的点
start[i] = n/sq * (i-1) + 1;
ed[i] = n/sq * i;
}
ed[sq] = n; //不要忘记!
for(int i = 1; i <= sq; i++)
for(int j = start[i]; j <= ed[i]; j++) {
bel[j] = i; //
}
for(int i = 1; i <= sq; i++)
size[i] = ed[i] - start[i] + 1;
}
vector<int> v[maxm]; //存排序后的数组
void update(int b) {
for(int i = 0; i < size[b]; i++)
v[b][i] = a[start[b] + i];
sort(v[b].begin(), v[b].end());
}
void solve() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
init(n);
for(int i = 1; i <= sq; i++)
for(int j = start[i]; j <= ed[i]; j++)
v[i].push_back(a[j]);
for(int i = 1; i <= sq; i++)
sort(v[i].begin(), v[i].end());
while(m--) {
char o;
scanf(" %c", &o);
if(o == 'A') {
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
int tot = 0;
if(bel[l] == bel[r]) {
for(int i = l; i <= r; i++)
if(mark[bel[i]] + a[i] >= c) tot++;
cout << tot << '\n';
continue;
}
for(int i = l; i <= ed[bel[l]]; i++)
if(mark[bel[i]] + a[i] >= c) tot++;
for(int i = start[bel[r]]; i <= r; i++)
if(mark[bel[i]] + a[i] >= c) tot++;
for(int i = bel[l] + 1; i < bel[r]; i++)
tot += v[i].end() - lower_bound(v[i].begin(), v[i].end(), c - mark[i]);
cout << tot << '\n';
}
else {
int l, r, w;
// cin >> l >> r >> w;
scanf("%d%d%d", &l, &r, &w);
if(bel[l] == bel[r]) {
for(int i = l; i <= r; i++) {
a[i] += w;
}
update(bel[l]);
continue;
}
else {
for(int i = l; i <= ed[bel[l]]; i++)
a[i] += w;
for(int i = start[bel[r]]; i <= r; i++) //不要漏bel[r] 查了半天
a[i] += w;
update(bel[r]);
update(bel[l]);
for(int i = bel[l] + 1; i < bel[r]; i++)
mark[i] += w;
}
}
}
}
signed main() {
// ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
// int T; scanf("%d", &T); while(T--)
// int T; cin >> T; while(T--)
solve();
return 0;
}