分块80pts求调(#1,#3,#11),玄关
  • 板块P2801 教主的魔法
  • 楼主dxt_
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/11 13:25
  • 上次更新2023/11/11 13:30:57
查看原帖
分块80pts求调(#1,#3,#11),玄关
542199
dxt_楼主2023/11/11 13:25
#include<bits/stdc++.h>
using namespace std;
const long long N=1e6+5;
long long a[N],b[N],l[N],r[N],pos[N],lazy[N];
long long t,p,n,m;
char f;
void update(long long x,long long y,long long k){
	long long p=pos[x],q=pos[y];
	if(p==q){
		for(long long i=x;i<=y;++i) a[i]+=k,b[i]=a[i];
		sort(b+l[p],b+1+r[p]);
		return;
	}
	for(long long i=p+1;i<=q-1;++i) lazy[i]+=k;
	for(long long i=x;i<=r[p];++i) a[i]+=k,b[i]=a[i];
	for(long long i=l[q];i<=y;++i) a[i]+=k,b[i]=a[i];
	sort(b+l[p],b+1+r[p]);sort(b+l[q],b+1+r[q]);
}
long long lowerbond(long long cnt,long long ll,long long rr,long long k){
	int res;
	while(ll<=rr){
		long long mid=ll+(rr-ll>>1);
		 if(b[mid]>=k) rr=mid-1,res=r[cnt]-mid+1;
		else if(b[mid]<k) ll=mid+1;
	}
	return res;
}
long long search(long long x,long long y,long long k){
	long long p=pos[x],q=pos[y];
	long long ans=0;
	if(p==q){
		for(long long i=x;i<=y;++i) if(a[i]+lazy[p]>=k) ++ans;
		return ans;
	}
	for(long long i=x;i<=r[p];++i)if(a[i]+lazy[p]>=k){
	++ans;}
//	else	cout<<i<<" "<<a[i]+lazy[p]<<endl;
	
	for(long long i=p+1;i<=q-1;++i){
		ans+=lowerbond(i,l[i],r[i],k-lazy[i]);
//		cout<<lowerbond(l[i],r[i]+1,k-lazy[i])-l[i]<<endl;
	}
	for(long long i=l[q];i<=y;++i) if(a[i]+lazy[q]>=k){
	++ans;}
//	else cout<<i<<" "<<a[i]+lazy[q]<<endl;
	
	return ans;
}
int main(){
	scanf("%lld%lld",&n,&m);
	for(long long i=1;i<=n;++i){
	scanf("%lld",&a[i]);
	b[i]=a[i];
	}
	t=sqrt(n);
	for(long long i=1;i<=t;++i){
	l[i]=t*(i-1)+1,r[i]=t*i;
	for(long long j=l[i];j<=r[i];++j) pos[j]=i;
	sort(b+l[i],b+r[i]+1);
	}
	if(r[t]<n){
	l[1+t]=r[t]+1,r[t+1]=n,t+=1;
	for(long long j=l[t];j<=r[t];++j) pos[j]=t;
	}
	while(m--){
		cin>>f;
		long long x,y;
		long long k;scanf("%lld%lld%lld",&x,&y,&k);
		if(f=='M')update(x,y,k);
		else printf("%lld\n",search(x,y,k));
	}
	return 0;
} 
2023/11/11 13:25
加载中...