0pts求调(dev5.11写的,空格稍微炸裂)
查看原帖
0pts求调(dev5.11写的,空格稍微炸裂)
1007879
May_to_July楼主2025/2/6 21:39
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}


//带_part的函数都是非整块处理 
const int N=1000006;
int a[N],d[N],bl[N],bll[N],blr[N],lazy[N]/*以bl为下标,存这个区块整体加多少*/;

///////////////////////////////// raise 
void raise_part(int bln/*block_number*/, int st, int ed,int x) {
	for(int i = st; i <= ed; i++) {
        a[i] += x;
    }
    int len=blr[bln]-bll[bln]+1;
    memcpy(d+bll[bln],a+bll[bln],len*sizeof(int));//好东西 
    sort(d+bll[bln],d+blr[bln]+1);
}
void raise(int st,int ed,int x){
	if(bl[st]==bl[ed]){
		raise_part(bl[st],st,ed,x);
		return;
	}
	raise_part(bl[st],st,blr[st],x);
	raise_part(bl[ed],bll[ed],ed,x);
	
	for(int i=bl[st]+1;i<bl[ed];i++){
		lazy[i]+=x;
	}
}
///////////////////////////////// asks 
int ask_part(int bln,int l,int r,int c){
	int ans=0;
	for(int i=l;i<=r;i++){
		if(a[i]+lazy[bln]>=c){
			ans++;
		}
	}
	return ans;
}
int ask(int l,int r,int c){
	if(bl[l]==bl[r]){
		return ask_part(bl[l],l,r,c);
	}
	int ans1=ask_part(bl[l],l,blr[bl[l]],c),
		ans2=ask_part(bl[r],bll[bl[l]],r,c),
		ans3=0;
	for(int i=bl[l]+1;i<bl[r];i++) {
        int now=lower_bound(d+bll[i],d+blr[i]+1,c-lazy[i])-d;//lower_bound返回迭代器! 
        ans3+=blr[i]-now+1;
    }
    return ans1+ans2+ans3; 
	
}
int main(){
	char c;
	int n=read(),q=read(),l,r;
	int block=int(sqrt(n)),cnt=(n+block-1)/block,x;
	for(int i=1;i<=n;i++)d[i]=a[i]=read();
	for(int i=1;i<=n;i++)bl[i]=(i-1)/block+1;
	for(int i=1;i<=cnt;i++){
		bll[i]=(i-1)*block+1;
		blr[i]=min(i*block,n);
		sort(d+bll[i],d+blr[i]+1);//为什么排序?
		//因为二分查找,有序后二分找到一个极点直接算个数 
	}
	for(int i=1;i<=q;i++){
		cin>>c>>l>>r>>x;
		if(c=='M'){
			raise(l,r,x);
		}else{
			printf("%d\n",ask(l,r,x));
		}
	}
	return 0;
}

2025/2/6 21:39
加载中...