程序中 个数查询函数 如何工作
查看原帖
程序中 个数查询函数 如何工作
547725
Zilljy258楼主2025/1/10 18:34

对于一个查询超过 ss 的元素个数操作,我会将他的答案乘以 ss,因为“询问操作转化为比 ss 大的都按照 ss 算求和”。

long long qryn(int x){
	long long ans=0;
	while(x){
		ans+=tn[x];
		x-=lowbit(x);
	}
	return ans;
}

然而当我尝试输出样例中 qryn(len) 时,他的答案是 0 。(lenlen 是离散化数组的大小,即最大值。)

有趣的是:这份代码竟然顺利通过样例并且 AC 了。

这说明(且经过我的验证) qryn(v-1) 是负数。(vv 就是 ss 离散化后的数值)

请问这是为什么?

谢谢%%%

贴上完整代码,可能是其他版块出现问题,具体已在文中标注。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define lowbit(i) (i&(-i))

using namespace std;

const int N=1e6+10;

int n,m;
int len;//离散化去重后的长度
long long a[N];//题面中序列的数值在离散化数组中的位置
long long ts[N<<1],tn[N<<1];//ts统计和,tn统计数字个数。

void adds(int x,long long z){ //加入新数字
	while(x<=len){
		ts[x]+=z;
		tn[x]++;  //我在这
		x+=lowbit(x);
	}
	return ;
}

void deln(int x,long long z){ //删除旧数
	while(x<=len){
		ts[x]-=z;
		tn[x]--;  //我在这
		x+=lowbit(x);
	}
	return ;
}

long long qrys(int x){ //求和
	long long ans=0;
	while(x){
		ans+=ts[x];
		x-=lowbit(x);
	}
	return ans;
}
long long qryn(int x){ //求个数
	long long ans=0;
	while(x){
		ans+=tn[x];
		x-=lowbit(x);
	}
	return ans;
}

struct question{
	int op;
	int x;
	long long z;
}q[N];

long long lsh[N]; //离散化数组
int ef(long long x){
	int l=1,r=len,mid;
	
	while(l<r){
		mid=(l+r+1)>>1;
		
		if(lsh[mid]>x){
			r=mid-1;
		}
		else{
			l=mid;
		}
	}
	
	return l;
}

signed main(){
	
	scanf("%lld%lld",&n,&m);
	
	for(int i=0;i<=n;++i){
		a[i]=1;
		adds(1,0);
	}
	
	char opp;
	lsh[1]=0;
	for(int i=1;i<=m;++i){
		scanf("\n%c%lld%lld",&opp,&q[i].x,&q[i].z);//进行离线
		
		if(opp=='U') q[i].op=0;
		else q[i].op=1;
		
		lsh[i+1]=q[i].z;
	}
	
	
	sort(lsh+1,lsh+m+2);
	len=unique(lsh+1,lsh+m+2)-lsh-1;
	
	int v;
	long long ans;
	for(int i=1;i<=m;++i){
		v=ef(q[i].z);
		
		if(!q[i].op){
			deln(a[q[i].x],lsh[a[q[i].x]]);
			adds(v,q[i].z);
			a[q[i].x]=v;
		}
		else{
			ans=qrys(v-1);//首先求小于 s 的数字和。
			ans+=(qryn(len)-qryn(v-1))*q[i].z; //然后大于等于 s 的都按 s 算。
//			cout<<qryn(v-1)<<endl;  //////////////////////////////////////////////就是这一行,他是0
//			cout<<qryn(v-1)<<endl;  //////////////////////////////////////////////就是这一行,他是负数
			if(ans>=q[i].x*q[i].z){
				printf("TAK\n");
			}
			else{
				printf("NIE\n");
			}
		}
		
	}
	
	
	return 0;
}

谢谢!/bx

2025/1/10 18:34
加载中...