大则分,分则合。
#include <bits/stdc++.h>
const int Max=1e6+5;
int N,M,S,SNum;char CH[3];
int A[Max],B[Max],Lazy[Max],Block[Max];
using namespace std;
int Find(int X,int V){
int I,J,K,L=(X-1)*S+1,R=min(X*S,N);K=R;
while(L<=R){
int Mid=L+R>>1;
if(B[Mid]<V){
L=Mid+1;
} else {
R=Mid-1;
}
}
return K-L+1;
}
void Set(int X){
int I,L=(X-1)*S+1,R=min(X*S,N);
for(I=L;I<=R;I++){
B[I]=A[I];
}sort(B+L,B+R+1);
}
void Update(int X,int Y,int W){
int I,J,K;
if(Block[X]==Block[Y]){
for(I=X;I<=Y;I++){
A[I]+=W;
}
Set(Block[X]);
} else {
for(I=X;I<=Block[X]*S;I++){
A[I]+=W;
}Set(Block[X]);
for(I=(Block[Y]-1)*S+1;I<=Y;I++){
A[I]+=W;
}Set(Block[Y]);
}
for(I=Block[X]+1;I<Block[Y];I++){
Lazy[I]+=W;
}
}
int GetAns(int X,int Y,int W){
int I,J,K,Ans=0;
if(Block[X]==Block[Y]){
for(I=X;I<=Y;I++){
if(A[I]+Lazy[Block[I]]>=W){
Ans++;
}
}
} else {
for(I=X;I<=Block[X]*S;I++){
if(A[I]+Lazy[Block[I]]>=W){
Ans++;
}
}
for(I=(Block[Y]-1)*S+1;I<=Y;I++){
if(A[I]+Lazy[Block[I]]>=W){
Ans++;
}
}
}
for(I=Block[X]+1;I<Block[Y];I++){
Ans+=Find(I,W-Lazy[I]);
}
return Ans;
}
int main(){
int I,J,K;
scanf("%d%d",&N,&M);
S=sqrt(N);SNum=N/S;
if(N%S){
SNum++;
}
for(I=1;I<=N;I++){
scanf("%d",&A[I]);
Block[I]=(I-1)/S+1;
}
for(I=1;I<=SNum;I++){
Set(I);
}
for(I=1;I<=M;I++){
int X,Y,W;
scanf("%s%d%d%d",CH,&X,&Y,&W);
if(CH[0]=='M'){
Update(X,Y,W);
} else {
printf("%d\n",GetAns(X,Y,W));
}
}
return 0;
}