Do basically anything that is correct. It probably suffices to do a DFS, where for every array, we branch on merging some pair of adjacent cities.
First, we don't want to deal with exponentially large numbers. Realize that if we merge two cities with population , we get . This means that we can redefine our merge operation to simply be , and our numbers are now at most .
Let be the sizes of the cities. When we say , we mean the cities . We say that an interval [l,r] is good if it is possible to merge the cities into a single city. Now, let us try to actually solve the subtask. When we are done merging cities, we will end up with multiple intervals that are merged into one. It is unclear exactly which cities should be part of which interval. So let us guess! Let us guess that cities and are not part of the same interval. What happens then? The problem splits into 2 independent parts! This motivates the following DP:
Then, we get:
How do we quickly compute whether is good? We precompute all good intervals using a new dp,
We have the base case for all . Similarly to the last dp, we will compute this one by guessing where the intervals go:
These types are dps are well-known to run in : states, and transitions per state. This solves subtask 2.
We can rethink to run in instead. We basically want to cover with the smallest number of good intervals. We can therefore go left to right and define
We can then see that the transitions are:
It should not be hard to see that this dp runs in in total. As there are at most good intervals, this is .
Now, we somehow need to optimize . It seems hard to remove state, so let us try removing transitions. We can realize that for each interval , can only be true for exactly zero or one . Suppose we have a that works: if we move it one step to the left or right, then we can't possibly merge the new intervals anymore. For subtask 3, it is easier to store numbers in the form . Under this form of addition, the sum of an interval never changes when we merge two numbers. Therefore, will be the number such that . Using binary search over a prefix sum of city sizes, this can be found (or determine that such a does not exist). .
However, this does not work as well for larger city sizes. Can we find a new invariant under the operation? This seems difficult. Instead, we will compute bottom-up. By doing this in a smart order, it is easy to quickly find other potential intervals to merge with and stay good. This solution will be discussed more in-depth later.
The insight that is key to solving this problem is a bit of leap of faith: it is that there are only good intervals.
How do you realize this? It feels very hard to solve the problem if there are good intervals. So you try generating a worst-case, but don't succeed. For example, create an array with size for some .
: 1 1 1 1
In this one, it is easy to see that there only good intervals: for every left endpoint, the only good right endpoints are the ones that are a power of 2 to the right of it. It seems unlikely that more complicated arrays have more good intervals, as it feels like it should be harder to merge lots of elements in them. Another example: 1 1 2 3 4 5. In this one, one left endpoint has lots of right endpoints, but the rest the left endpoints can't merge to the right.
Contest tip: "prove" this by using previous solutions that finds all good intervals, together with an assert: maybe something of the style
And then you can try lowering/increasing the 2 based on your results. Use the online judge to "prove" your conjectures!
Now, how do we design a solution using this insight? This actually instantly gives us that calculating only takes time, as it ran in the number of intervals. Now, we have to find all good intervals. This is unfortunately harder.
We will find all good intervals by computing bottom-up. The base case is that every interval [i,i] is good. How can we merge intervals? Interval can be merged with interval if . So one possible way to compute this dp is by throwing all intervals into a priority queue, where the ones with smallest come first. Among the ones with the same , we process them right to left. This runs in . Why? Every time an interval looks at another interval, it finds a new good interval. As there are at most good intervals, and we do a heap operation for each one, we end up with in total.
As this task is brutal and , this will probably only give 45 points due to TLE. So we need to remove the log-factor. To optimize the solution, we will process intervals grouped by their (it is impossible to merge ones with different , after all). The goal is to be able to process all intervals with , then the ones with etc. For the first group, we the intervals by their left endpoint. Now, our problem is:
for every interval , check if the interval exists for some . By going through the intervals in reverse order (large left endpoints first), this can be done in linear time.
We also need to construct the array , the intervals created from this iteration. By going the intervals right to left, we can generate the new intervals for sorted by left endpoint, so we don't need to sort! (Although will be reversed, so we do need to reverse it back). However, we still missed a detail; there may be intervals with value of size (the ones from the initial array). You will have to carefully insert these in at the same time as you add the newly created intervals, so that it remains reverse-sorted. If you every need to call sort on , it's probably going to be too slow.
In total, we take for every created good interval and for every initial interval (those of size 1). So in total, we get . If you implement this carefully and with a good constant factor, it is enough to solve the problem.
Let =the smallest number in . Consider any interval of 's of maximal size (that is to say, it can't be extended left or right). We'll call this a block. Lemma 1: every good interval uses an even number of the numbers from each block (possibly 0). There are four types of ways that a block can be used:
Let be the size of this block. We will now do the following:
Iterate the previous process until we are left with an array containing only equal numbers. If the array has elements, it should be easy to see that this array has good intervals. Note that this number includes the count of all fake intervals created when we reduce odd blocks. What about the ones that we destroyed? For every block along the way, we remove some amount of elements . When these elements were removed, we also removed good intervals (the ones within the block). Thus, we remove at most intervals along the way. This gives that the sum of the number of good intervals is at most . Q.E.D.
The solution has two parts, which are about equally painful to implement. First, we fully find the graph. Then, in the second part, we get all the rats in the correct spots.
We do this by going through all nodes, and finding all of their neighbors. This procedure does not work for leaf nodes, and since we don't know from the start which ones are leaves, we will have to pretend that there are no leaves for now…
You do this procedure for every node in the graph. Since it is important that there is a rat on the node V in the beginning, you have to think about what order to do this.
Once you've done this, you still have the issue of leaf nodes. It turns out that in step 4 in the above procedure, once you've already found the "true" neighbor of a leaf node, it might give you some false neighbors as well. So we will have found the graph, with extra stuff.
The way we deal with this is by first filtering out edges that seem directed (where a is connected to b but b not connected to a), and then finding all triangles in the graph (3-cycles), cutting of the edge between the two nodes in the triangle with the highest values. This should finally give us the full graph.
Now that we have the full graph, we can actually simulate the queries: It is deterministic what will happen for a given query. This idea allows us to do a divide&conquer procedure, where we split the graph into several components, decide what queries to do in each component, and then merge the queries together. This allows us to greatly reduce the number of queries needed.
The algorithm works as follows:
In this part of the code, we don't actually perform any queries, only calculate which queries we should make in order to get all the rats to the correct spots. Then when we're all done, we merge the queries together and perform all of them.
Let's say we have a valid subset of signs. We call a subset of signs valid if there is no 2 signs in this subset that contradict each other. Notice that we can do the following opeartions to the signs, and the subset of signs will still be valid:
Using these 2 operations, we can normalize all signs in the following way:
Now all values on the signs will be non-negative, and the sign will only consist of s.
For example if we had the following 3 signs with 2 values each:
and we normalize the values based on the first sign, we will first turn all the signs into:
and then subtract the smallest value on each sign.
If we assume is one of the correct signs in the optimal valid subset, then if any sign contains a value larger than , then that sign cannot be in this valid subset. Through this method, we eliminate most of the signs that are not valid. However, that is not sufficient to eliminate all invalid signs.
is small here. We can try all subsets of signs, check if the subset is a valid solution.
Note that if a subset is valid, we can choose any of the signs in the subset to be , the sign that all other signs will get normalized against. One can convince themselves that this is true.
To check if a subset is a valid solution, we normalize the signs, and check if there is any value that is larger . If there is, then this subset is not valid. After that, we sort the signs based on the sum of the values on each sign. Since in a valid subset of signs, the sum of the values of the sign closest to Stockholm will be the largest. Now we can check in linear time if this subset is correct.
We have to check for each pair of consecutive signs, if the values on each index is non-decreasing.
For example, this subset of normalized signs is invalid:
Since from sign 2 to sign 3, the value on the second index is decreasing there is no way to place these 3 signs so that the signs are not contradicting.
Notice that this subset of signs are valid though:
You can also think that if we check the signs the top to bottom, once an index has been activated, it cannot be deactivated again.
The optimal answer will be the largest valid subset. Through the method above we know the indicies of the signs that construct the optimal subset of signs.
We take the indicies and sort these signs by the sum of the signs' original values. This works because of a similar reason as stated above, that the sum of the values in a valid subset will be the largest when it is closest to Stockholm, and the sums will be in a decreasing order when we get closer to Gothenburg.
This results in a solution that is
Let's costruct a graph. So for each sign that we set as (the one we normalize against), we can construct a graph where each sign is a node, and we add an edge from sign to sign if for all .
Notice that by doing this, an edge will be added if and only if you can place the sign after the , when is normalized.
What we want to find now is the longest path in this directed graph. This can be found in .
It will take to construct a graph for a specific sign that we normalize against. This results in a time complexity, since we construct a graph for every sign.
We still want to construct the same graph, however there is one way to make it much faster to construct each edge.
Notice that after we have normalized all signs, all values should be either 0 or 1 (if it is not 0 or 1, then that sign can't be valid). This means that instead of comparing all elements when we are comparing , we can just create a bitset and compare the bitsets. This saves us a huge factor and results in a time complexity.
We can save another factor by using the fact that at least of the signs are correct.
As mentioned earlier, if we normalize according to any sign that is in the optimal subset, then we will successfully find the optimal subset of signs.
This means if we only create graphs by randomly choose random signs to normalize agianst. By running 40 times, the probability that we fail is very small.
This results in a , which is sufficient to solve the problem. We also note that there exists a deterministic solution running in , but leave it as an exercise for the reader.