不知道哪错了,但只过了#14的测试点,剩下的点WA+TLE+RE+MLE
#include<bits/stdc++.h>
using namespace std;
const int S=1000;
int maxx,a[1000001],res,n,m,ans[500001],L[1000000/S+1],R[1000000/S+1],l[500001],r[500001],x[500001],opt[500001];
int fa[S+1],rt[100003],ntr[100003];
short size[100003];
int read(){
int num,sign=1;
char c;
while((c=getchar())<'0'||c>'9')if(c=='-') sign=-1;
num=c-'0';
while((c=getchar())>='0'&&c<='9')num=(num<<3)+(num<<1)+c-'0';
return num*sign;
}
inline int find(int u){
return fa[u]==u?u:fa[u]=find(fa[u]);
}
inline void update(int k,int id){
if(maxx-res<=x[id])return;
if(maxx-res<=x[id]<<1){
for(int i=x[id]+1+res;i<=maxx+res;i++){
if(rt[i-x[id]]){
fa[rt[i]]=rt[i-x[id]];
rt[i]=0;
ntr[rt[i]]=0;
}else{
ntr[rt[i]]=i-x[id];
rt[i-x[id]]=rt[i];
rt[i]=0;
}
size[i-x[id]]+=size[i];
size[i]=0;
}
maxx-=x[id];
}else{
for(int i=x[id]+res;i>=res;i--) {
if(rt[i+x[id]]&&i+x[id]<=maxx){
fa[rt[i]]=rt[i+x[id]];
size[i+x[id]]+=size[i];
ntr[rt[i]]=0;
rt[i]=0;
}else{
size[i+x[id]]=size[i];
ntr[rt[i]]=i+x[id];
rt[i+x[id]]=rt[i];
rt[i]=0;
}
size[i]=0;
}
res+=x[id];
}
}
inline void modify(int k,int xx,int ll,int rr){
maxx=-0x3f3f3f3f;
int bel=(ll-1)/S+1;
for(int i=L[bel];i<=R[bel];i++){
a[i]=ntr[find(i-L[k]+1)]-res;
maxx=max(a[i],maxx);
}
res=0;
for(int i=L[bel]-10;i<=R[bel]+10;i++){
if(i<0)continue;
rt[a[i]]=0;
size[a[i]]=0;
fa[i]=0;
}
for(int i=ll;i<=rr;i++){
if(a[i]>xx){
a[i]-=xx;
}
}
memset(ntr,0,sizeof(ntr));
for(int i=L[bel];i<=R[bel];i++){
if(!rt[a[i]]){
ntr[i-L[k]+1]=a[i];
rt[a[i]]=i-L[k]+1;
fa[i-L[k]+1]=i-L[k]+1;
}else{
fa[i-L[k]+1]=rt[a[i]];
}
size[a[i]]++;
}
}
inline int query(int k,int xx,int ll,int rr){
int sum=0;
for(int i=ll;i<=rr;i++){
if(ntr[find(i-L[k]+1)]-res==xx){
sum++;
}
}
return sum;
}
int main(){
n=read();
m=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<=m;i++){
opt[i]=read();
l[i]=read();
r[i]=read();
x[i]=read();
}
for(int i=1;i<=(n-1)/S+1;i++){
L[i]=(i-1)*S+1;
R[i]=i*S;
}
R[(n-1)/S+1]=n;
for(int k=1;k<=(n-1)/S+1;k++){
memset(fa,0,sizeof(fa));
memset(ntr,0,sizeof(ntr));
memset(rt,0,sizeof(rt));
memset(size,0,sizeof(size));
res=0;
maxx=-0x3f3f3f3f;
for(int i=L[k];i<=R[k];i++){
maxx=max(maxx,a[i]);
if(!rt[a[i]]){
ntr[i-L[k]+1]=a[i];
rt[a[i]]=i-L[k]+1;
fa[i-L[k]+1]=i-L[k]+1;
}else{
fa[i-L[k]+1]=rt[a[i]];
}
size[a[i]]++;
}
for(int j=1;j<=m;j++){
if(opt[j]==1){
if(l[j]<=L[k]&&R[k]<=r[j]){
update(k,j);
}else if(L[k]<=l[j]&&r[j]<=R[k]){
modify(k,x[j],l[j],r[j]);
}else if(L[k]<=l[j]&&l[j]<=R[k]){
modify(k,x[j],l[j],R[k]);
}else if(L[k]<=r[j]&&r[j]<=R[k]){
modify(k,x[j],L[k],r[j]);
}
}else{
if(l[j]<=L[k]&&R[k]<=r[j]){
ans[j]+=size[x[j]+res];
}else if(L[k]<=l[j]&&r[j]<=R[k]){
ans[j]+=query(k,x[j],l[j],r[j]);
}else if(L[k]<=l[j]&&l[j]<=R[k]){
ans[j]+=query(k,x[j],l[j],R[k]);
}else if(L[k]<=r[j]&&r[j]<=R[k]){
ans[j]+=query(k,x[j],L[k],r[j]);
}
}
}
}
for(int i=1;i<=m;i++){
if(opt[i]==2){
printf("%d\n",ans[i]);
}
}
return 0;
}