Editorial for Yet Another Contest 9 P3 - Divide and Delete
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Subtask 1
First, let's try to determine whether a given array is good. Consider the -th element, . This element's index can only ever decrease, so it can never be divided by a number greater than . Thus, a necessary condition is that for each , is a product of positive integers not exceeding ; this is equivalent to saying that the largest prime factor of is at most .
On the other hand, this condition is also sufficient. We can show this inductively:
- If the array is empty, we are already done.
- Otherwise, for each , while is divisible by , divide by . After this, the largest prime factor of is now at most , since it was at most before division, and does not divide .
- Delete the first element, which is allowed since is guaranteed to be for arrays satisfying the condition.
- Now, every other element's index decreases by 1, but the condition still holds. So we can inductively show that the remaining array can be made empty.
We can precalculate the largest prime factor of each integer from up to by modifying the Sieve of Eratosthenes.
For convenience, define as the largest prime factor of . We now know that the condition for the subarray spanning the indexes to be valid is that for all . For this subtask, it is sufficient to brute force all , and loop to find the largest such that the subarray is valid.
Time complexity:
Subtask 2
We need to speed up the counting of valid subarrays.
For a fixed , define index as blocking if and only if . The condition that the subarray spanning the indexes is valid is now equivalent to saying that there are no blocking indexes between and .
Loop from down to . The key insight here is that once an indexes stops becoming blocking, it will never become blocking again for any smaller . Thus, it suffices to maintain a stack of all blocking indexes. That is, when we try a new , we first add onto the stack, and then pop off from the stack whilst the top element is non-blocking. The largest value of such that the subarray is valid is now the value on the top of the stack, minus .
Alternatively, for each , we can binary search for the largest such that subarray is valid, though we need a quick way to check whether is valid. This can be done efficiently using a sparse table, or by walking down a segment tree.
Time complexity: or
Comments