求助P2801,60分死活过不去:P
  • 板块学术版
  • 楼主D_FANG
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/7/28 14:20
  • 上次更新2023/11/3 07:14:18
查看原帖
求助P2801,60分死活过不去:P
635829
D_FANG楼主2023/7/28 14:20
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,q;
struct rec{
	long long d;
	int i;
}a[1000010];
bool cmp(rec x,rec y){
	return x.d<y.d;
}
long long lz[100010];//每个块加上的z
int st[100010],ed[100010],cnt[1000010];
int finds(int l,int r,int z){//手写lower_bound
	while (l<=r){
		int mid=(l+r)>>1;
		if (a[mid].d>=z){
			r=mid-1;
		}
		else l=mid+1;
	}
	if (a[l].d<z){
		return -1;
	}
	return l;
}
int m,l,r,z;
char op;
int main(){

//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d%d",&n,&q);
	int s=sqrt(n);//块的长度
	int en=1;
	for (int i=1;i<=n;i++){
		scanf("%lld",&a[i].d);
		cnt[i]=en;//节点i属于哪个块
		a[i].i=i;
		if (i%s==0){
			ed[++m]=i;
			st[m]=i-s+1;
			en++;
		}
	}	
	for (int i=1;i<=m;i++){
		sort(a+1+(i-1)*s,a+i*s+1,cmp);
	}if (s*s!=n){
		ed[++m]=n;
		st[m]=s*s+1;
		sort(a+s*s+1,a+n+1,cmp);
	}

	for (int i=1;i<=q;i++){
		cin>>op;
		scanf("%d%d%d",&l,&r,&z);
		if (op=='A'){
			int sum=0;
			if (cnt[l]==cnt[r]){
				for (int j=st[cnt[l]];j<=ed[cnt[r]];j++){
					if (a[j].i>=l&&a[j].i<=r&&a[j].d>=z-lz[cnt[l]]){
						sum++;
					}
				}
			}
			else{
				for (int j=cnt[l]+1;j<cnt[r];j++){
					int s=finds(st[j],ed[j],z-lz[j]);
					if (s!=-1){
						sum+=ed[j]-s+1;
					}
				}
				for (int j=st[cnt[l]];j<=ed[cnt[l]];j++){
					if (a[j].i>=l&&a[j].i<=r&&a[j].d>=z-lz[cnt[l]]){
						sum++; 
					}
				} 
				for (int j=st[cnt[r]];j<=ed[cnt[r]];j++){
					if (a[j].i>=l&&a[j].i<=r&&a[j].d>=z-lz[cnt[r]]){
						sum++; 
					}
				}
			}
			printf("%d\n",sum);
		}
		if (op=='M'){
			if (cnt[l]==cnt[r]){
				for (int j=l;j<=r;j++){
					a[j].d+=z;
				}
				sort(a+st[cnt[l]]+1,a+ed[cnt[l]]+1,cmp);
			}
			else{
				for (int j=cnt[l]+1;j<=cnt[r]-1;j++){
					lz[j]+=z;
				}
				for (int j=st[cnt[l]];j<=ed[cnt[l]];j++){
					if (a[j].i>=l&&a[j].i<=r){
						a[j].d+=z;
					}
				} 
				for (int j=st[cnt[r]];j<=ed[cnt[r]];j++){
					if (a[j].i>=l&&a[j].i<=r){
						a[j].d+=z;
					}
				}
				sort(a+st[cnt[l]]+1,a+ed[cnt[l]]+1,cmp);
				sort(a+st[cnt[r]]+1,a+ed[cnt[r]]+1,cmp);
			}
		}
	}
	return 0;
}
2023/7/28 14:20
加载中...