CF 1598C

本文探讨如何通过计算平均值,找出删除一对数后序列保持平均值不变的策略。作者分享了一种二分查找的方法,以及在处理非整数平均值时的解决方案,核心在于利用平均值的等式推导。

Delete Two Elements

大致题意

给定一个序列,求出他的平均值,删除任意两个元素,如果序列平均值不变,那么这个对就是对的,平均值不一定是整数

思路

最先的想法就是 根据 s u m sum sum的平均值乘2,去二分查找另一个数的上界和下界, a n s ans ans每次加上值,但是很可惜,wa了,因为平均值不一定是整数,
冷静分析一手,
( s u m − a − b ) / ( n − 2 ) = s u m / n (sum-a-b)/(n-2)=sum/n (sumab)/(n2)=sum/n
↓ \downarrow
( s u m − a − b ) × n = s u m × ( n − 2 ) (sum-a-b)\times n = sum\times(n-2) (sumab)×n=sum×(n2)
( a + b ) × n = s u m × 2 (a+b) \times n=sum\times2 (a+b)×n=sum×2

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
#define tle ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define var int n,m,res,ans,t,x,y,z,a,b,c,g[N];
#define x first
#define y second
const int N = 2e5+111;
using namespace std;
var
signed main(){
	//tle
	cin>>t;int idx=1;
	while(t--){
		cin>>n;int sum=0;ans=0;
		for(int i=1;i<=n;++i) cin>>g[i],sum+=g[i];
		sort(g+1,g+1+n);
		if(sum*2%n) {
			cout<<0<<endl;
			continue;
		}
		sum=sum*2/n;
		for(int i=1;i<=n;++i){
			int x=sum-g[i];
			if(x<0) continue;
			a=lower_bound(g+i+1,g+1+n,x)-g;
			b=upper_bound(g+i+1,g+1+n,x)-g;
			if(g[a]==g[b-1])ans+=(b-a);
		}
		cout<<ans<<endl;
	}	
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值