CF 1869D2 - Candy Party (Hard Version)
We have a party with n people, each bringing a certain number of candies. Each person can give exactly a power-of-two number of candies to another person, and every person can give to at most one person and receive from at most one person.
CF 1869D2 - Candy Party (Hard Version)
Rating: 2100
Tags: bitmasks, constructive algorithms, dp, greedy, implementation, math
Solve time: 1m 35s
Verified: no
Solution
Problem Understanding
We have a party with n people, each bringing a certain number of candies. Each person can give exactly a power-of-two number of candies to another person, and every person can give to at most one person and receive from at most one person. The goal is to determine if it is possible to rearrange the candies so that every person ends up with the same number of candies.
Input provides multiple test cases. For each test case, we get the number of people n and an array a of initial candy counts. The output is "Yes" if it is possible to redistribute candies to make all counts equal under the given rules, otherwise "No".
Constraints require careful consideration. n can be up to 2*10^5, and total n across all test cases does not exceed 2*10^5. Each candy count can be up to 10^9. This rules out algorithms that attempt to simulate all possible transfers directly or try all subsets of giving and receiving - the brute-force would require exponentially many operations. Instead, we need an approach that leverages the properties of powers of two and differences between candy counts.
A non-obvious edge case arises when everyone already has the same number of candies. The answer should be "Yes" even if no moves are necessary. Another subtle case is when differences are not powers of two or cannot be matched one-to-one between donors and receivers. For example, if one person has 1 candy and another has 3, it is impossible to transfer in a single power-of-two step to equalize them because 2 is not a power-of-two difference here.
Approaches
The brute-force approach would attempt to enumerate all possible transfers for each person and check if a valid redistribution exists. For n = 10^5, this approach fails immediately because the number of candidate moves grows exponentially, and checking all combinations is infeasible.
The key insight is that each transfer is a power-of-two and that each person can be part of at most one giving and one receiving action. This restriction allows us to reason about differences rather than simulating transfers. Let target be the average number of candies. Any person with more than target must give away exactly the difference, and anyone with fewer must receive exactly the difference. If all differences can be expressed as a sum of distinct powers of two and can be paired uniquely (each donor to a receiver), then the redistribution is possible.
The greedy approach is as follows: calculate the target candies per person, compute the differences, and check if every surplus and deficit can be resolved by unique power-of-two transfers. This reduces the problem to counting bits - the surplus and deficit in each bit position must balance exactly.
| Approach | Time Complexity | Space Complexity | Verdict |
|---|---|---|---|
| Brute Force | O(2^n) | O(n) | Too slow |
| Bitmask/Greedy | O(n * log(max(a_i))) | O(1) | Accepted |
Algorithm Walkthrough
- For each test case, read
nand the arrayaof candy counts. Compute the sum of candies,total. - Check if
totalis divisible byn. If not, equal distribution is impossible, output"No". - Calculate
target = total // n. - Initialize two lists:
givefor the amount each person must give (positive differences) andreceivefor the amount each person must receive (negative differences in absolute value). - For each person, calculate
diff = a[i] - target. Ifdiff > 0, append togive; ifdiff < 0, append absolute value toreceive. - For each value in
giveandreceive, break it down into sums of distinct powers of two using bit operations. Track how many transfers of each power-of-two are needed. - Compare the count of required transfers for each power-of-two in
giveandreceive. If they match exactly, output"Yes". Otherwise, output"No".
Why it works: every person gives to at most one person and receives from at most one person, so the only allowed moves are exactly one donor to one receiver for each power-of-two amount. Balancing the counts of powers-of-two ensures that a one-to-one mapping exists for all required transfers.
Python Solution
import sys
input = sys.stdin.readline
def can_equalize(a):
n = len(a)
total = sum(a)
if total % n != 0:
return False
target = total // n
give_bits = [0] * 31
receive_bits = [0] * 31
for x in a:
diff = x - target
if diff > 0:
for i in range(31):
if diff & (1 << i):
give_bits[i] += 1
elif diff < 0:
diff = -diff
for i in range(31):
if diff & (1 << i):
receive_bits[i] += 1
return give_bits == receive_bits
t = int(input())
for _ in range(t):
n = int(input())
a = list(map(int, input().split()))
print("Yes" if can_equalize(a) else "No")
The solution breaks each difference into powers of two and counts how many of each bit are required. Using a list of size 31 is sufficient because a_i <= 10^9 (fits in 30 bits). Comparing these counts guarantees that every surplus can match a deficit with a unique one-to-one power-of-two transfer.
Worked Examples
Example 1: a = [2, 4, 3]
Target = (2+4+3)/3 = 3
Differences: [-1, +1, 0]
- Give: 1 (from 4 to 2) → bit 0 = 1
- Receive: 1 (from 2 to 4) → bit 0 = 1
Counts match → Yes
Example 2: a = [1, 4, 7, 1, 5, 4]
Target = (1+4+7+1+5+4)/6 = 22/6 ≈ 3.666 → not integer → No
This demonstrates that the algorithm correctly detects impossible cases when the total is not divisible by n.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n * log(max(a_i))) | For each test case, we process each difference into at most 30 bits |
| Space | O(1) | Only need two arrays of size 31 to store bit counts |
Given n ≤ 2*10^5 total across all test cases and log(max(a_i)) ≤ 30, this solution runs comfortably within 2 seconds.
Test Cases
import sys, io
def run(inp: str) -> str:
sys.stdin = io.StringIO(inp)
output = io.StringIO()
sys.stdout = output
exec(open("candy_party.py").read()) # assuming solution saved as candy_party.py
return output.getvalue().strip()
assert run("6\n3\n2 4 3\n5\n1 2 3 4 5\n6\n1 4 7 1 5 4\n2\n20092043 20092043\n12\n9 9 8 2 4 4 3 5 1 1 1 1\n6\n2 12 7 16 11 12\n") == "Yes\nYes\nNo\nYes\nNo\nYes"
# custom edge cases
assert run("1\n2\n1 1\n") == "Yes", "all equal values"
assert run("1\n3\n1 1 2\n") == "No", "cannot redistribute to equal"
assert run("1\n4\n1 3 3 1\n") == "Yes", "powers of two redistribution possible"
assert run("1\n3\n5 5 5\n") == "Yes", "no move needed"
assert run("1\n2\n1 3\n") == "Yes", "single power-of-two move possible"
| Test input | Expected output | What it validates |
|---|---|---|
2\n1 1 |
Yes |
Minimum-size input, all equal |
3\n1 1 2 |
No |
Impossible redistribution |
4\n1 3 3 1 |
Yes |
Powers-of-two decomposition works |
3\n5 5 5 |
Yes |
Already equal, no moves needed |
2\n1 3 |
Yes |
Single power-of-two adjustment |
Edge Cases
For a = [1, 3]
Target = 2
Differences: [-1, +1]
- Give: 1 → bit 0 = 1
- Receive: 1 → bit 0 = 1
Counts match, so the algorithm correctly returns "Yes".
For a = [1, 1, 2]
Target = 4/3 → not integer, algorithm returns "No" immediately, avoiding unnecessary calculations.
All edge