求助,下载数据输出一毛一样,但是全wa
查看原帖
求助,下载数据输出一毛一样,但是全wa
778886
brucelei658楼主2024/6/6 16:27

全红,然后我下载第一组数据后发现答案是一样的,这是啥原因

#include<bits/stdc++.h>
using namespace std;
/*panda*/
#define pb push_back
#define bug printf("*********\n");
#define INF 0x3f3f3f3f
#define fs first
#define sc second
#define mem0(a) memset(a, 0, sizeof(a));
#define memf(a) memset(a, 0x3f, sizeof(a));
#define f(i,a,b) for(int i = a;i<=b;++i)
#define f_(i,a,b) for(int i = a;i>=b;--i)
typedef long long ll;
#define pii pair<ll,ll>
typedef unsigned long long ull;
void read(int &x){int f=1;x=0;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}x*=f;}
const int N =1e6+10;
int ar[N];
int e[N];//原数组的副本,用于排序
int be[N];//表示第i个下标属于哪个块 
int L[1010],R[1010];//第i个块的左边界和右边界 
int tag[1010];//懒标记 
int n,q;
char op,l,r,k; 

void slove(){
	cin>>n>>q;
	f(i,1,n){
		scanf("%d",&ar[i]);
 	}
 	
	int block = int(sqrt(double(n)));//块长 
	int tot = (n+block-1)/block;//该分多少块 
	f(i,1,n)e[i] = ar[i];
	for(int i = 1;i<=tot;i++){
		L[i] = (i-1) * block+1;
		R[i] = min(i*block,n);
		for(int j = L[i];j<=R[i];j++){
			be[j] = i;
		}
		sort(e+L[i],e+R[i]+1);
	}
//	auto cg = [&](int k){
//		f(i,L[k],R[k])e[i]=ar[i];
//		sort(e+L[k],e+R[k]+1);
//	};
	while(q--){
		cin>>op;
		scanf("%d%d%d",&l,&r,&k);
		//增加 
		if(op == 'M'){
			if(be[l] == be[r]){
				f(i,l,r)ar[i]+=k;
				f(i,L[be[l]],R[be[l]])e[i]=ar[i];
				sort(e+L[be[l]],e+R[be[l]]+1);
			}else{
				//左边块的操作 
				for(int i = l;i<=R[be[l]];i++)ar[i]+=k;
				//右边块的操作
				for(int i = L[be[r]];i<=r;i++)ar[i]+=k;
				f(i,L[be[l]],R[be[l]])e[i]=ar[i];
				sort(e+L[be[l]],e+R[be[l]]+1);;
				f(i,L[be[r]],R[be[r]])e[i]=ar[i];
				sort(e+L[be[r]],e+R[be[r]]+1); 
				//中间部分块整体+ 
				for(int i = be[l]+1;i<=be[r]-1;i++)tag[i]+=k;
			}
		}
		//查询有多少个大于k的数据 
		else {
			int ans = 0;
			if(be[l] == be[r]){
				f(i,l,r){
					ans+= (ar[i] + tag[be[l]] ) >= k ;
				}
			}else{
				for(int i = l;i<=R[be[l]];i++)ans += (ar[i]+tag[be[l]])>=k;
				for(int i = L[be[r]];i<=r;i++)ans += (ar[i]+tag[be[r]])>=k;
				//否者每个块二分找大于=k-tag[i]的下标,因为懒标记还没加,所以减去 
				for(int i = be[l]+1;i<=be[r]-1;i++){
					//第i个块的左右下标 
					int x = L[i],y = R[i]; 
					int p = y+1+e-lower_bound(e+x,e+y+1,k-tag[i]);
					ans+=p;
				}
			}
			printf("%d\n",ans);
		}
	}
}






int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int _ = 1;
//	cin>>_;
	while(_--)slove();
	return 0;
}












2024/6/6 16:27
加载中...