首先我們想這樣的問題,爲什麼強調是\(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;
}