关于P2801的离谱数据
  • 板块灌水区
  • 楼主ssl_lwz
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/8/24 11:22
  • 上次更新2023/11/3 01:34:33
查看原帖
关于P2801的离谱数据
484751
ssl_lwz楼主2023/8/24 11:22
#include<bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;
int n,m,a[N],b[N],bel[N],add[N];
int st[N],ed[N],t;
void copy(int x){
	for(int i=st[x];i<=ed[x];i++)
	  b[i]=a[i]; 
	sort(b+st[x]+1,b+ed[x]+1);
}
void build(){
	for(int i=1;i<=t;i++){
		st[i]=n/t*(i-1)+1;
		ed[i]=n/t*i;
	}
	ed[t]=n;
	for(int i=1;i<=t;i++)
	  for(int j=st[i];j<=ed[i];j++)
	    bel[j]=i;
}
void update(int x,int y,int c){
	//(x,y)+c
	if(bel[x]==bel[y]){
	    for(int i=x;i<=y;i++)
		  a[i]+=c;
		copy(bel[x]);
		return;
	}
	for(int i=x;i<=ed[bel[x]];i++){
	    a[i]+=c;
		copy(bel[x]);
	}
	for(int i=st[bel[y]];i<=y;i++){
	    a[i]+=c;copy(bel[y]);
	}	   
	for(int i=ed[bel[x]]+1;i<st[bel[y]];i++)
	   add[i]+=c;
}
int find(int x,int c){  //在块x中 
	//找>=c的个数
	int z=st[x],y=ed[x];
	while(z<=y){
		int mid=(z+y)>>1;
		if(b[mid]+add[x]<mid)  z=mid+1;
		else y=mid-1;
	} 
	return ed[x]-z+1;
}
int ser(int x,int y,int w){
	int ans=0;
	if(bel[x]==bel[y]){
		for(int i=x;i<=y;i++)  ans+=(a[i]+add[i]>=w);
		return ans;
	}
	for(int i=x;i<=ed[bel[x]];i++)
	  ans+=(a[i]+add[i]>=w);
	for(int i=st[bel[y]];i<=y;i++)
	  ans+=(a[i]+add[i]>=w);
	for(int i=bel[x]+1;i<bel[y];i++)
	  ans+=find(i,w);
	return ans;
}
int main() {
	ios::sync_with_stdio(false);
    cin>>n>>m;
    t=sqrt(n);
    for(int i=1;i<=n;i++)  cin>>a[i];
  //  build();
    for(int i=1;i<=t;i++)
      cout<<st[i]<<" "<<ed[i]<<endl; 
    for(int i=1,x,y,w;i<=m;i++){
    	char c;
    	cin>>c>>x>>y>>w;
    	if(c=='M'){
    		update(x,y,w);
		}  
    	else{
    		cout<<ser(x,y,w)<<endl;
		}
	}
	return 0;
}
2023/8/24 11:22
加载中...