这是问题的简化版本。唯一的区别是,在该版本中,每个人必须给一个人糖果,并从一个人那里接收糖果。请注意,一次性提交不能同时通过问题的两个版本。只有在解决了问题的两个版本后,才能进行黑客攻击。
在中考之后,丹尼尔和他的朋友们要举办一个派对。每个人都会带一些糖果来。
派对上会有n个人。初始时,第i个人有ai个糖果。派对期间,他们将交换他们的糖果。为此,他们将以任意顺序排队,并且每个人仅执行以下操作一次:
Plain Text
选择一个整数p(1≤p≤n)和一个非负整数x,然后将他的2x个糖果给第p个人。请注意,不能给出比他当前拥有的糖果更多的糖果(他之前可能从其他人那里接收到糖果),也不能把糖果给自己。
丹尼尔喜欢公平,所以只有当每个人都从一个人那里接收到糖果时他才会开心。与此同时,他的朋友汤姆喜欢均等,所以只有当所有人在全部交换后拥有相同数量的糖果时他才会开心。
确定是否存在一种交换糖果的方法,以使得丹尼尔和汤姆在交换后都会开心。 输入
输入的第一行包含一个整数t(1≤t≤1000) - 测试用例的数量。后续是描述每个测试用例的行。
每个测试用例的第一行包含一个整数n(2≤n≤2⋅105) - 派对上的人数。
每个测试用例的第二行包含n个整数a1,a2,…,an(1≤ai≤109) - 每个人拥有的糖果数量。
保证所有测试用例中n的总和不超过2⋅105。 输出
对于每个测试用例,如果存在一种交换糖果的方式使得丹尼尔和汤姆都开心,请打印"Yes"(不带引号),否则打印"No"(不带引号)。
您可以输出答案的任何大小写形式。例如,字符串"yEs"、"yes"、"Yes"和"YES"都将被识别为肯定回答。 示例 输入 复制
6 3 2 4 3 5 1 2 3 4 5 6 1 4 7 1 5 4 2 20092043 20092043 12 9 9 8 2 4 4 3 5 1 1 1 1 6 2 12 7 16 11 12
输出 复制
Yes Yes No Yes No No
注意
第一个测试用例中:
Plain Text
第一个人给第三个人1个糖果;
第二个人给第一个人2个糖果;
第三个人给第二个人1个糖果。
然后所有人都有3个糖果。
第二个测试用例中:
Plain Text
第五个人给第一个人4个糖果,此时第一个人有5个糖果;
第一个人给第三个人2个糖果;
第三个人给第五个人2个糖果;
第四个人给第二个人2个糖果;
第二个人给第四个人1个糖果。
然后所有人都有3个糖果。注意,刚开始时第一个人不能给第三个人2个糖果,因为他只有a1=1个糖果。但是在第五个人给他4个糖果之后,他就可以这样做了,因为他目前有1+4=5个糖果。
第三个测试用例中,所有人都拥有相同数量的糖果是不可能的。
第四个测试用例中,第一个人给第二个人1024个糖果,同时第二个人也给第一个人1024个糖果。
题解:
题目中说每个人一定要接受2^?的礼物,那么肯定每个人也会给出去2^?的礼物
如果总和无法被平均直接输出NO
否则应该满足a[i] - 2^q + 2^p = x
x为平均值
我们变一下形 2^p - 2^q = a[i] - x
右边为一个固定的值w,这时候牵扯到一个规律
假设这个值成立,那么肯定有唯一确定的p和q导致其成立,
证明:
10000..p个0 - 10000q个0 均是二进制位
最后的结果形式一定是1111...0....这样的形式
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> PII;
multiset<int> s;
const int N = 5e5 + 10;
int a[N];
void solve()
{
int n;
cin >> n;
int s = 0;
for(int i = 1;i <= n;i++)
{
cin >> a[i];
s += a[i];
}
if(s%n != 0)
{
cout <<"NO\n";
return ;
}
s /= n;
int f = 1;
vector<int> u(100),v(100);
for(int i = 1;i <= n;i++)
{
f = 1;
for(int j = 0;j < 40;j++)
{
for(int k = 0;k < 40;k++)
{
if(a[i] - (1ll << j) + (1ll << k) == s&&f)
{
u[j]++;
v[k]++;
f = 0;
break;
}
}
}
if(f)
{
cout <<"NO\n";
return ;
}
}
if(u == v)
{
cout <<"YES\n";
}
else
{
cout <<"NO\n";
}
}
signed main()
{
int t = 1;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> t ;
while(t--)
{
solve();
}
}
//环