P2801 教主的魔法

发布时间 2023-06-22 15:31:49作者: incra

include

include

include

using namespace std;
const int N = 1000010;
int n,m;
int a[N],b[N];
int L[N],R[N],pos[N];
int add[N];
void modify (int l,int r,int x) {
int p = pos[l],q = pos[r];
if (p == q) {
for (int i = l;i <= r;i++) a[i] += x;
for (int i = L[p];i <= R[p];i++) b[i] = a[i];
sort (b + L[p],b + R[p] + 1);
return ;
}
for (int i = p + 1;i <= q - 1;i++) add[i] += x;
for (int i = l;i <= R[p];i++) a[i] += x;
for (int i = L[p];i <= R[p];i++) b[i] = a[i];
sort (b + L[p],b + R[p] + 1); //注意左闭右开
for (int i = L[q];i <= r;i++) a[i] += x;
for (int i = L[q];i <= R[q];i++) b[i] = a[i];
sort (b + L[q],b + R[q] + 1);
}
int query (int l,int r,int x) {
int p = pos[l],q = pos[r];
if (p == q) {
int cnt = 0;
for (int i = l;i <= r;i++) cnt += a[i] + add[p] >= x;
return cnt;
}
int cnt = 0;
for (int i = p + 1;i <= q - 1;i++) {
int l = L[i],r = R[i];
while (l < r) {
int mid = l + r >> 1;
if (b[mid] + add[i] >= x) r = mid;
else l = mid + 1;
}
if (b[l] + add[i] >= x) cnt += R[i] - l + 1; // 注意
}
for (int i = l;i <= R[p];i++) cnt += a[i] + add[p] >= x;
for (int i = L[q];i <= r;i++) cnt += a[i] + add[q] >= x;
return cnt;
}
int main () {
scanf ("%d%d",&n,&m);
for (int i = 1;i <= n;i++) scanf ("%d",&a[i]),b[i] = a[i];
int len = sqrt (n);
for (int i = 1;i <= len;i++) L[i] = (i - 1) * len + 1,R[i] = i * len;
if (R[len] < n) len++,L[len] = R[len - 1] + 1,R[len] = n;
for (int i = 1;i <= len;i++) {
for (int j = L[i];j <= R[i];j++) pos[j] = i;
}
/*
不能写成这样:
for (int i = 1;i <= n;i++) pos[i] = (i - 1) / n + 1;
/
for (int i = 1;i <= len;i++) sort (b + L[i],b + R[i] + 1);
while (m--) {
char op[2];
int l,r,x;
scanf ("%s%d%d%d",op,&l,&r,&x);
if (
op == 'M') modify (l,r,x);
else printf ("%d\n",query (l,r,x));
}
return 0;
}