D1. Candy Party (Easy Version)
This is the easy version of the problem. The only difference is that in this version everyone must give candies to exactly one person and receive candies from exactly one person. Note that a submission cannot pass both versions of the problem at the same time. You can make hacks only if both versions of the problem are solved.
After Zhongkao examination, Daniel and his friends are going to have a party. Everyone will come with some candies.
There will be $n$ people at the party. Initially, the $i$-th person has $a_i$ candies. During the party, they will swap their candies. To do this, they will line up in an arbitrary order and everyone will do the following exactly once:
- Choose an integer $p$ ($1 \le p \le n$) and a non-negative integer $x$, then give his $2^{x}$ candies to the $p$-th person. Note that one cannot give more candies than currently he has (he might receive candies from someone else before) and he cannot give candies to himself.
Daniel likes fairness, so he will be happy if and only if everyone receives candies from exactly one person. Meanwhile, his friend Tom likes average, so he will be happy if and only if all the people have the same number of candies after all swaps.
Determine whether there exists a way to swap candies, so that both Daniel and Tom will be happy after the swaps.
Input
The first line of input contains a single integer $t$ ($1\le t\le 1000$) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer $n$ ($2\le n\le 2\cdot 10^5$) — the number of people at the party.
The second line of each test case contains $n$ integers $a_1,a_2,\ldots,a_n$ ($1\le a_i\le 10^9$) — the number of candies each person has.
It is guaranteed that the sum of $n$ over all test cases does not exceed $2\cdot 10^5$.
Output
For each test case, print "Yes" (without quotes) if exists a way to swap candies to make both Daniel and Tom happy, and print "No" (without quotes) otherwise.
You can output the answer in any case (upper or lower). For example, the strings "yEs", "yes", "Yes", and "YES" will be recognized as positive responses.
Example
input
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
output
Yes Yes No Yes No No
Note
In the first test case:
- The first person gives $1$ candy to the third person;
- The second person gives $2$ candies to the first person;
- The third person gives $1$ candy to the second person.
Then all people have $3$ candies.
In the second test case:
- The fifth person gives $4$ candies to the first person, from now on the first person has $5$ candies;
- The first person gives $2$ candies to the third person;
- The third person gives $2$ candies to the fifth person;
- The fourth person gives $2$ candies to the second person;
- The second person gives $1$ candy to the fourth person.
Then all people have $3$ candies. Note that at first the first person cannot give $2$ candies to the third person, since he only has $a_1=1$ candy. But after the fifth person gives him $4$ candies, he can do this, because he currently has $1+4=5$ candies.
In the third test case, it's impossible for all people to have the same number of candies.
In the fourth test case, the first person gives $1024$ candies to the second person, and the second person gives $1024$ candies to the first person as well.
解题思路
由于最后每个人分到的糖果数量一样,因此如果$n \nmid \sum\limits_{i=1}^{n}{a_i}$那么无解。定义平均数$m = \frac{\sum\limits_{i=1}^{n}{a_i}}{n}$,那么最终每个人分到的糖果数量就是$m$。
在这个版本中要求每个人都必须给恰好一个人分糖果,同时必须收到恰好一个人的糖果,如果第$i$个人给第$j$个人糖果那么连一条从$i$到$j$的有向边$i \to j$,那么就会得到由若干个长度至少为$2$的环构成的图。这是因为每个节点的出度和入度都恰好为$1$,且没有自环。
由于每个人给出以及收到的糖果数量都是$2^x$的形式,因此最终每个人都要满足$x_i - 2^{x_i} + 2^{y_i} = m$,其中$2^{x_i}$表示第$i$个人给出的糖果数量,$2^{y_i}$表示第$i$个人收到的糖果数量。如果有$a_i = m$那么只需满足$2^{x_i} = 2^{y_i}$,而可以取任意值。下面主要讨论$a_i \ne m$的情况。
如果$a_i \ne m$,那么有$a_i - m = 2^{x_i} - 2^{y_i}$,对于被减数和减数都是$2$的整次幂这种形式,模拟一下可以发现得到的结果在二进制下连续的$1$至多有$1$段。比如$(11100)_2$,$(111)_2$,$(0)_2$都是合法的结果,而$(11001)_2$,$(1010)_2$都不是合法的结果。因此在枚举时如果发现$a_i - m$不满足这个条件,那么无解。
假设每个$a_i - m$都满足上面的条件(一样不考虑$a_i = m$的情况),定义由$x_i$构成的集合$S = \left\{ x \mid x = x_i, \, x_i \ne y_i \land i \in[1,n] \right\}$,以及由$y_i$构成的集合$T = \left\{ y \mid y = y_i, \, x_i \ne y_i \land i \in[1,n] \right\}$,如果$S = T$,那么必然有解,否则无解。如果$S = T$,对于$S$中每个元素$x_i$总是可以在$T$中找到值相同的元素$y_j$,并且必有$i \ne j$,此时从$i$到$j$连一条有向边,权值为$x_i$,表示第$i$个人给第$j$个人$x_i$个糖果,那么就会构造出一种分发方案,每个人都恰好给一个人糖果和收到一个人的糖果,且最后每个人的糖果数量均为$m$。
还有个细节就是还需满足每个人给出的糖果不得超过当前获得的糖果数量这个条件。这个证明其实还是比较难的,比赛的时候只要最后有$S=T$那么就猜有解直接交了,没考虑到这个条件,现在来补一下证明。由于每个人给糖果的顺序可以是任意的,那么在每个环中只要选择的起点满足$a_i - 2^{x_i} \geq 0$,那么剩下的节点由于满足$a_j + 2^{y_j} - 2^{x_j} = m > 0 \Longrightarrow a_j + 2^{y_j} > 2^{x_j}$,因此这个条件就得到满足。可以证明环中最大的$a_i$必然满足$a_i - 2^{x_i} \geq 0$。
选择环中最大的$a_i$,此时必然有$a_i > m$,假设第$i$个人给第$j$个人糖果,那么有$1 \leq a_j \leq a_i$,我们要得到$$\begin{align*} a_i-2^{x_i}+2^{y_i} &= m \tag{1} \\ a_j-2^{x_j}+2^{x_i} &= m \tag{2} \end{align*}$$
假设$a_i - 2^{x_i} < 0$,那么必然有$2^{y_i} < 2^{x_i}$,即$y_i + 1 \leq x_i$。
如果$x_i < x_j$,$$\begin{aligned} (1)-(2) &\implies a_i-a_j-2^{x_i}+2^{x_j}+2^{y_i}-2^{x_i}=0\\\\ &\implies a_i-a_j+\underbrace{(2^{x_j}-2\cdot 2^{x_i})+2^{y_i}}_{>0}=0\\ &\implies a_i-a_j<0 \\\\ &\implies a_i < a_j \end{aligned}$$
与$a_i \geq a_j$矛盾了。
如果$x_i > x_j$,$$\begin{aligned} (2)-(1) &\implies a_j-a_i-2^{x_j}+2^{x_i}+2^{x_i}-2^{y_i}=0\\ &\implies a_j=a_i+(2^{x_j}+2^{y_i})-2^{x_i+1}\\ &\implies a_j\leq a_i+(2^{x_i-1}+2^{x_i-1})-2^{x_i+1}\\ &\implies a_j\leq a_i-2^{x_i}\\ &\implies a_j\leq 0 \end{aligned}$$
与$a_j \geq 1$矛盾了。
因此在每个环中选择最大的$a_i$作为起点,那么在交换时每个人给出的糖果数量一定不会超过当前的糖果数量。
最后再考虑回$a_k = m$的情况,只需插在环中任意两个点间即可,比如$i \xrightarrow{x_i} j$,那么可以构造$i \xrightarrow{x_i} k \xrightarrow{x_i} j$。
另外一个细节就是如何判定某个数$x$在二进制下连续的$1$是否至多有$1$段。只需判断$x + \operatorname{lowbit}(x)$在二进制下$1$的个数是否不超过$1$即可。
AC代码如下,时间复杂度为$O(n \log{A})$:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 2e5 + 10; 7 8 int a[N]; 9 int cnt[31]; 10 11 int lowbit(int x) { 12 return x & -x; 13 } 14 15 void solve() { 16 int n; 17 scanf("%d", &n); 18 LL m = 0; 19 for (int i = 0; i < n; i++) { 20 scanf("%d", a + i); 21 m += a[i]; 22 } 23 if (m % n) { 24 printf("NO\n"); 25 return; 26 } 27 m /= n; 28 memset(cnt, 0, sizeof(cnt)); 29 for (int i = 0; i < n; i++) { 30 if (a[i] == m) continue; 31 int x = abs(a[i] - m); 32 if (__builtin_popcount(x + lowbit(x)) > 1) { 33 printf("NO\n"); 34 return; 35 } 36 int l = __lg(lowbit(x)), r = __lg(x + lowbit(x)); 37 if (a[i] < m) cnt[l]++, cnt[r]--; // a[i] - 2^l + 2^r 38 else cnt[r]++, cnt[l]--; // a[i] - 2^r + 2^l 39 } 40 for (int i = 1; i <= 30; i++) { 41 if (cnt[i]) { 42 printf("NO\n"); 43 return; 44 } 45 } 46 printf("YES\n"); 47 } 48 49 int main() { 50 int t; 51 scanf("%d", &t); 52 while (t--) { 53 solve(); 54 } 55 56 return 0; 57 }
参考资料
Codeforces Round 896 (Div. 1, Div. 2) Editorial:https://codeforces.com/blog/entry/116642
标签:candies,person,int,Version,Easy,Party,gives,糖果,first From: https://www.cnblogs.com/onlyblues/p/17701777.html