Editorial for Yet Another Contest 4 P6 - No More Solitaire
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
There are many heuristics that can be applied to this problem. Some of them are mentioned below here.
Solution 1: Prime factorisation
We can try to solve the problem by considering each prime factor independently, and combining them at the end. For each prime factor , there are elements which contain as a factor. We can find the lowest index such that is a multiple of using binary search; then, we disregard all elements with indices and repeat the process to find the rest of the elements. Once we have found all elements which are multiples of , we can repeat the same process, binary searching on these elements, to find the elements which are multiples of , and so on. This is sufficient for of the points.
Our algorithm now consists of multiple rounds; in each round, we need to find elements which are multiples of out of a set containing indices. Let's try to optimise each round.
Currently, with our binary searches, we use slightly less than queries. A simpler strategy is to query of the indices in the set individually to determine which elements are multiples of . If we combine the two strategies, we can perform a round in no more than queries. This is sufficient for of the points.
There is a more complicated strategy to perform a round. First, query the lowest elements in the set. If at least one of these elements is a multiple of , then we perform our binary search as before to find the desired element. Otherwise, we can remove these elements from the set, and repeat the process. This uses no more than queries. The optimal value of is different for each round, and can be found using a binary or ternary search. This is sufficient for of the points. Notice that by choosing , we perform the linear search from before, and by choosing , we perform the binary search from before. Thus, we can forget about implementing the linear or binary search separately.
Let be the current product of the factors of that we have found so far, at any time in our algorithm. Originally, for all , and when our algorithm finishes, for all . When we perform a round checking for multiples of the power of some prime , for each element that we find, our algorithm multiples by . Consider performing all rounds checking multiples of powers of , then performing all rounds checking multiples of powers of , and so on for each prime. Then, we notice that once for the current prime , must equal , since cannot be multiplied later on in our algorithm without exceeding . This means that for all future rounds, we can discard checking element . In this manner, we can reduce the size of the sets of indices that we check in each round. This is sufficient to obtain of points. For full points, we need a different approach…
Solution 2: Finding elements in order, abusing randomness
Instead of trying to find the prime factorisation of each number, we can try the easier strategy of directly finding the position of each element in some order. If we are trying to find the position of element , then we would want to avoid querying any subarray that contains any multiple of (other than ). Thus, it makes intuitive sense to find the position of elements in descending order; then, when we try to find the position of element , we would already know which subarrays to avoid.
The positions of the multiples of (other than ) will be known, and they will split the entire range into several subranges. We can only glean information by querying within a single subrange. Note that our query allows us to determine if element is present in a given subarray, as long as that subarray is part of a single subrange.
Now, we will abuse the randomness of the data. We will start by determining which subrange element lies in. This can be done by iterating through the subranges in decreasing order of length, short-circuiting when we find the required subrange; this is optimal as longer subranges are more likely to contain element . If we get to the final subrange, then we do not need to waste an extra query since this final subrange must contain element .
Once we have found the subrange that element lies in, a simple binary search suffices to find its exact position. Some positions within this subarray may already be known to contain other values, so these positions can be excluded from the binary search. If all optimisations are made, full points will be obtained.
Comments