I encountered this Codeforces problem with some really interesting and remarkable ideas, so I decided to write a short note about it. This solution is partly based off an explanation by CF user aryanc403.
We are given integers , , and . An array of non-negative integers is good if and . We are asked to compute the bitwise XOR of all elements of all good arrays.
Formally, let the score of an array be . We want to compute the total score (bitwise XOR) of the scores of all good arrays.
High-Level Overview
This can seem like an intimidating problem. One way to get started is to write a brute force and see if there are any patterns in small cases. Alternatively, the fact that we are dealing with XOR instead of addition or multiplication indicates that we can utilize some very nice symmetric properties about XOR. Here's a simple observation we can make that illustrates this point:
Lemma: If is even, the total score is .
Proof. First note that in a palindrome of even length , each element appears an even number of times, so its score is , and it does not contribute to the total. Thus let's only consider non-palindromic good arrays. For any good array , consider its reverse , which is also a good array. We can compute the total score by pairing up arrays and their reverse (e.g., ). For each pair and , the two arrays contain the same elements, so . Thus the total score is also .
This simple proof illustrates an important concept that we will use later: if we have a set and an involution (i.e., for all ), we can compute the parity of the size of by counting the number of elements fixed by . In other words, we can pair up elements in a set that cancel each other out.
Definitions
Let's collect some terminology we will use:
- The binary representation of a nonnegative integer is the unique set of powers of that sum to .
- If and are integers, we say is a submask of (sometimes written ) if the powers of in the binary representation of are also in the binary representation of . For instance, is a submask of but not .
Overview
Our high-level plan will be as follows. Since any element in a good array will be a submask of , the total score will also be a submask of . Therefore let's compute the total answer by counting the total contribution of each power of in the binary representation of . If appears an odd number of times among all elements of all good arrays, then we add to the answer; otherwise, we add .
So, for each power of , we want to count the parity of the number of times it appears among all good arrays. We will need some way of representing the conditions that the sum of a good array is , and that the bitwise OR of a good array is . However, it turns out that this bitwise OR condition is a bit unwieldy, and it is easier to work with the relaxed constraint that the bitwise OR is simply a submask of . We can recover the original constraint by using the inclusion-exclusion principle and considering all submasks of .
This sounds good so far, but we still haven't dealt with the meat of the problem: counting the number of arrays whose sum is with some particular constraints. Moreover, by using inclusion-exclusion and considering each power of independently, we have forced ourselves to iterate over (bit, mask) pairs, so ideally, we would be able to compute this number in constant time or at least . Since we are only concerned with the parity of the number of arrays, it turns out we can compute this in with the help of some number theory (Lucas' Theorem) and some clever pairing-up arguments.
Details
Matrix Fun
We assume is odd. (As shown above, the even case is trivial.) Let be the powers of in the binary representation of . For instance, if , then . If is a good array, since , is a submask of . We can imagine "redistributing" the bits in to produce a new good array.
More precisely, given a good array , let be the number of elements that have in their binary representation. Since , and there are elements in an array, . Let . Since , we have , and there are
ways to redistribute bits to obtain new good arrays with the same vector. Each good array corresponds to some , and we can compute the total score by computing the scores of each of the good arrays corresponding to . If is even, then since each appears an even number of times, the score of all arrays is . If is odd, the score of all arrays is the XOR of all , where is odd.
By Lucas' Theorem, is odd if and only if is a submask of . In order for to be odd, all must be odd, so is a submask of for all . Therefore, let's rewrite our equation into a form where we are only considering solutions where is a submask of . Let be the powers of in the binary representation of (since is odd, let's assume for notational convenience). Then since is a submask of , we can represent with the row vector , where and . Let be the matrix of all , so
Then
Each possible binary matrix corresponds to a choice of where each is a submask of . Let's call matrix valid if . For each valid matrix where each row in has a nonzero entry (i.e., ), we add to the XOR-sum for each such that (i.e., is odd).
Inclusion-Exclusion
Let's compute the total score by computing the contribution of each . We will add to our total score exactly when there is an odd number of valid matrices with . However, recall that needs to satisfy the bitwise OR condition as well: for each , we must have , which means that for each , at least one in the 'th row must be . The problem is that this is a difficult constraint to work with; we've already used this binary matrix representation to encode the constraint that each must be a submask of , but it's harder to force each row to have a nonzero element.
Let's work around this problem by relaxing this constraint, and then recovering the original answer using the inclusion-exclusion principle over all submasks of . More precisely, suppose is a submask of . Let be the parity of the number of matrices where and the 'th row in is allowed to have nonzero entries only when is in the binary representation of . Importantly, we don't require here that . Then . This is the same idea as regular inclusion-exclusion, except we don't have to worry about signs since we only care about parity.
So now all we have to do is solve this relaxed problem for each and each submask . The issue is that there are submasks and powers of to handle, so we're already up to complexity, and we still haven't dealt with how to count the number of solutions to this very large subset sum problem. However, keep in mind that we are only interested in the parity of the number of solutions, and this is again where symmetry comes into play.
Consider some valid matrix . For each nonzero entry , we can think of as "selecting" a pair of terms to sum to . Instead of thinking of our solution space as all possible binary matrices , let's think of it as multisets of terms of the form , where we select some subset to sum to . Then it turns out we have a simple condition to determine the parity of the number of ways to sum to :
Lemma. Let be a multiset of powers of whose sum is . The number of ways to select a subset of to sum to is odd if and only if is a submask of .
Proof. Suppose we have two equal numbers in our multiset; let's call them and . If we have a subset that includes but not , we can pair it up with a nearly identical subset that includes but not , and these two subsets have the same sum. Thus if we have two equal numbers in our multiset, we only have to count the number of solutions where we either include both of them or ignore both of them, since by this pairing argument, the number of solutions where we include just one of them is even. However, if we are always either including or ignoring two terms equal to some power , we might as well replace them with the single term .
More precisely, if our multiset is , there is a bijection between
and
Note that these two multisets maintain the same sum.
Moreover, we can repeat this process of replacing two copies of with until we have no more duplicate numbers in our multiset. At the end of this process, we have some set of unique powers of whose sum is still , which either has a unique subset whose sum is , or there are no subsets that sum to . We can form a sum of exactly when is a submask of .
Let's apply this observation to solve our subproblem. Given and a submask , our multiset is the set of terms (which are all powers of since and are powers of ), where is in the binary representation of . Since , has sum . We can assume that , so let's take this out of our multiset, so now our multiset is with sum . By our lemma, we have an odd number of solutions if and only if is a submask of .
Putting it all together
To summarize:
- Count the contribution of each bit independently.
- Use inclusion-exclusion to sum over all submasks of .
- We can solve this relaxed subproblem by checking if is a submask of .
Despite some of the elaborate reasoning required, the resulting implementation is remarkably simple. I'll leave my submission here for reference.
Vandermonde Solution
The editorial provides a shorter method of arriving at the same implementation of the solution described above using Lucas' theorem and Vandermonde's identity. Again, we'll count the contribution of each power of in the binary representation of and use inclusion-exclusion to XOR-sum over all submasks of . We wish to count the parity of the number of solutions to
where each is a submask of , and is in the binary representation of . (Since each provides the same contribution to the total score and is odd, the total score is equal to the contribution of a single .) We can assume we have already added to the sum, so then must be a submask of . Using Lucas' theorem, we can encode these submask constraints as the parity of
since this product will be odd if and only if each binomial coefficient is odd, which requires that is a submask of (or in the case of ). Thus, we can count the parity of the number of solutions as
By Vandermonde's identity, this is equal to
Again by Lucas' theorem, we just need to check if is a submask of ! You will occasionally see Lucas' theorem show up as a way of determining the parity of binomial coefficients, but this is the first time I've seen it used the other way around, using combinatorial identities to make checking subsets easier.
Anyways, I really enjoyed this problem and felt like I gained a much better understanding by writing this up. I hope you found it useful as well.