Official

Ex - K-th beautiful Necklace Editorial by en_translator


Step 1: There are \(O(3^{\frac{N}{3}})\) kinds of necklaces

Let \(n_c\) the number of jewelries with Color \(c\). There are \(\prod_{c=1}^{C}n_c\) kinds of necklaces. How big is this value? In other words, consider maximizing \(\prod_c n_c\) subject to \(\sum_c n_c=N\).

When \(N\neq 1\), if there exists \(c\) such that \(n_c=1\), we can repaint the jewelry in another existing color to obtain more kinds of necklaces, because \(1+x>1\times x\). Thus, in the optimal solution, there is no \(c\) such that \(n_c=1\).
If there are three or more \(c\)’s such that \(n_c=2\), we can repaint the three colors of six jewelries with two jewelries of each color to two colors of six jewelries with three jewelries of each color to obtain more kinds of necklaces, because \(3^2\gt 2^3\). Thus, in the optimal solution, there is at most two \(c\)’s such that \(n_c = 2\).
If there exists \(c\) such that \(n_c\geq 4\), we may repaint two of them in a different color without decreasing the number of kinds of necklaces, because \(2(n_c-2) \geq n_c\). Thus, we may assume that there is no \(c\) such that \(n_c \geq 4\) in the optimal solution.
Therefore, the optimal solution for \(N\geq 2\) is to have \(n_c=3\) for all \(c\) except for two of them, which have \(n_c=2\). By consider three cases of the remainder of \(N\) divided by \(3\), the claim in the beginning is justified.

Step 2: Meet-in-the-middle + binary search

Let \(P\) be the number of kinds of necklaces \(\prod_c n_c\). By the result of Step 1, we cans see that \(P\) is fairly small: \(P\leq 4\times 3^{22} \leq 1.3\times 10^{11} \). Therefore, this problem can be solved with the meet-in-the-middle technique as follows:

Split the set of colors into two disjoint sets \(A\) and \(B\) so that \(\prod_{c\in A}n_c\) and \(\prod_{c\in B}n_c\)are equal. Enumerate the \(\prod_{c\in A}n_c\) ways to choose the jewelry of colors in \(A\) and \(\prod_{c\in B}n_c\) ways in \(B\), which can be done in a total of \(O(3^{\frac{N}{6}})\) time. Let us denote them by \(\{A_i\}\) and \(\{B_i\}\), respectively. By storing \(\{B_j\}\) in a binary trie, we can obtain the number of \(j\) such that \(A_i \ {\rm XOR}\ B_j \geq x\) for any \(x\) and \(i\) in an \(O(\log V)\) time. Therefore, we can do binary search for the answer to solve the problem in a total of \(O(3^{\frac{N}{6}} (\log V)^2)\) time. However, even with fast languages like C or C++, it may be difficult to fit in the time limit.

Step 3: Reducing the complexity

The binary search in which the answer is determined from the most significant bit to the least has a lot of waste, because we visit the same node repeatedly for each \(A_i\). By resuming from the node we already visited, the cost is reduced to \(O(\log V)\) for the entire binary search for each \(A_i\), for a total of \(O(3^{\frac{N}{6}} \log V)\).

The implementation may become easier by maintaining the pair of “\(\{B_j\}\) under the current node” and “\(\{A_i\}\) that reaches the node” instead of actually constructing a binary trie.

Sample code (Python)

posted:
last update: