CF1869D1 Candy Party (Easy Version)

发布时间 2023-09-25 19:57:02作者: Simex

Link

首先我们想这样的问题,为什么强调是\(2^x\) 呢?我们记平均值是 \(avg\),然后可以注意到,应该有一下式子被满足

\(a_i-2^{x_i}+2^{y_i}=avg\),移项,可以得到\(a_i-avg=2^{y_i}-2^{x_i}\),而这个式子中\(x_i\)\(y_i\)有没有解和怎么解,是相当显然的,

我们把\(x_i\)\(y_i\)求出来分别放到两个集合中,显然二者组成的集合应改完全相同才行。

但是问题来了,为什么这么做就一定对呢?

证明参考这位大佬

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
#define int long long
using namespace std;
int n;
int a[200005];
int t;
int sum;
int cnt[50];
int lowbit(int x){
	return x&(-x);
}
int pl=-1;
int cal(int x){
	pl=-1;
	int cntt=0;
	for(int i=0;i<=30;++i){
		if(((1<<i)&x)!=0){
			if(pl==-1)
				pl=i;
			cntt++;
		}
	}
	return cntt;
}
int lo(int x){
	for(int i=0;i<=30;++i){
		if(((1<<i)&x)!=0){
			return i;
		}
	}
}
signed main(){
	scanf("%lld",&t);
	while(t--){
		sum=0;
		memset(cnt,0,sizeof(cnt));
		scanf("%lld",&n);
		for(int i=1;i<=n;++i)
			scanf("%lld",&a[i]);
		for(int i=1;i<=n;++i){
			sum+=a[i];
		}
		if(sum%n!=0){
			printf("No\n");
			continue;
		}
		sum/=n;
		bool f=1;
		for(int i=1;i<=n;++i){
			if(a[i]==sum) continue;
			int d=abs(a[i]-sum);
			int tem=d+lowbit(d);
			if(cal(tem)==1){
				if(a[i]>sum) {
					cnt[lo(tem)]++;
					cnt[lo(lowbit(d))]--;
				}else{
					cnt[lo(tem)]--;
					cnt[(lo(lowbit(d)))]++;
				}
			}else{
				f=0;
				break;
			}
		}
		if(f==0){
			printf("No\n");
			continue;
		}else{
			for(int i=0;i<=30;++i){
				if(cnt[i]!=0){
					f=0;break;
				}
			}
			if(f){
				printf("Yes\n");
			}else{
				printf("No\n");
			}
		}
	}
	return 0;
}