CF1869D1 Candy Party (Easy Version)
首先我们想这样的问题,为什么强调是\(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;
}