分块,有T有W
  • 板块P2801 教主的魔法
  • 楼主WsW_花逝爆零人
  • 当前回复4
  • 已保存回复4
  • 发布时间2023/7/12 17:25
  • 上次更新2023/11/3 10:16:40
查看原帖
分块,有T有W
349824
WsW_花逝爆零人楼主2023/7/12 17:25
#include<bits/stdc++.h>
using namespace std;
struct block{
	int st,ed,size;
	int tag;
}k[1010];
int n,q;
int len;
vector<int> v[1010];
int a[1000005],bel[1000005];
inline void update(int x){
	for(int i=0;i<k[x].size;i++)v[x][i]=a[i+k[x].st];
	sort(v[x].begin(),v[x].end());
}
inline void add(int l,int r,int ad){
	if(bel[l]==bel[r]){
		for(int i=l;i<=r;i++)a[i]+=ad;
		update(bel[l]);
		return ;
	}
	for(int i=l;i<=k[bel[l]].ed;i++)a[i]+=ad;
	for(int i=k[bel[r]].st;i<=r;i++)a[i]+=ad;
	for(int i=bel[l]+1;i<bel[r];i++)k[i].tag+=ad;//整块修改不改变排序 
	update(bel[l]);
	update(bel[r]);
}
inline int find(int l,int r,int w){
	int cnt=0;
	if(bel[l]==bel[r]){
		for(int i=l;i<=r;i++){
			if(a[i]+k[bel[i]].tag>=w){
				cnt++;
			}
		}
		return cnt;
	}
	for(int i=l;i<=k[bel[l]].ed;i++){
		if(a[i]+k[bel[i]].tag>=w){
			cnt++;
		}
	}
	for(int i=k[bel[r]].st;i<=r;i++){
		if(a[i]+k[bel[i]].tag>=w){
			cnt++;
		}
	}
	for(int i=bel[l]+1;i<bel[r];i++){
		cnt+=v[i].end()-lower_bound(v[i].begin(),v[i].end(),w-k[i].tag);
	}
	return cnt;
	
}
int main(){
	scanf("%d%d",&n,&q);
	len=sqrt(n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=len;i++){
		k[i].st=n/len*(i-1)+1;
		k[i].ed=n/len*i;
		k[i].size=k[i].ed-k[i].st+1;
		for(int j=k[i].st;j<=k[i].ed;j++){
			bel[j]=i;
			v[i].push_back(a[j]);
		}
		sort(v[i].begin(),v[i].end());
	}
	while(q--){
		char opt;
		int l,r,w;
		cin>>opt;
		scanf("%d%d%d",&l,&r,&w);
		if(opt=='M'){
			add(l,r,w);
		}
		else{
			printf("%d\n",find(l,r,w));
		}
	}
	return 0;
}
2023/7/12 17:25
加载中...