Codeforces Round #310 Editorial

Revision en15, by Lord_F, 2015-06-29 15:40:24

Hello, everyone!

556A - Case of the Zeros and Ones

If there still exist at least one 0 and at least one 1 in the string then there obviously exists either substring 01 or substring 10 (or both) and we can remove it. The order in which we remove substrings is unimportant: in any case we will make min(#zeros, #ones) such operations. Thus the answer is #ones + #zeros - 2min(#ones, #zeros) = |#ones - #zeros|.

Time: O(n).

556B - Case of Fake Numbers

Notice that after pressing the button n times gears return to initial state. So the easiest solution is to simulate the process of pressing the button n times and if at some step the active teeth sequence is 0, 1, ... , n - 1 output "Yes" else "No". But this solution can be improved. For instance, knowing the active tooth of the first gear you can quickly determine how many times pressing the button is necessary, go to that state and check the sequence only once.

Time: O(n) or O(n2); solutions: O(n) and O(n^2)

555A - Case of Matryoshkas

Suppose we don't need to disassemble some sequence of dolls. Then no doll can be inserted into no doll from this chain. So we don't need to disassemble a sequence of dolls only if they are consecutive and start from 1. Let the length of this chain be l. Then we will need to get one doll from another n - k - l + 1 times. Now we have a sequence 1 → 2 → ... → l and all other dolls by themselves. n - l + 1 chains in total so we need to put one doll into another n - l times. 2n - k - 2l + 2 operations in total.

Time: O(n); solution.

555B - Case of Fugitive

We can put a bridge between bridges i and i + 1 if its length lies in the segment [li + 1 - ri;ri + 1 - li]. Now we have a well-known problem: there are n - 1 segments and m points on a plane, for every segment we need to assign a point which lies in it to this segment and every point can be assigned only once.

Let's call a segment open if no point is assigned to it. Let's go through all points from left to right and at every moment keep all open segments that contain current point in a BST (std::set). When processing a point it should be assigned to the segment (from our set) that has the leftmost right end.

This algorithm will find the answer if there is one. Suppose this solution is wrong and suppose there is a solution in which point A is assigned to another open segment (there's no sense in skipping this point). Then some point B is assigned to the segment which A was assigned to. B is to the right of A so we can swap them and come to our answer again.

Time: O((n + m)log(n + m)); solution.

555C - Case of Chocolate

Let's solve this problem with two segment trees: we'll keep the lowest eaten piece for each column in one of them and the leftmost eaten piece for each row in another. Suppose we have a query x y L. Position where we'll stop eating chocolate is stored in the row segment tree so we can easily find the number of eaten pieces. After that we need to update both segment trees.

n is rather big in this problem. One way to deal with it is to use coordinate compression. Another is to use implicit segment trees.

Time: O(qlogq) or O(qlogn); solutions: 1 and 2.

555D - Case of a Top Secret

I call the length of the part of the rope from the weight to the last met peg the active length (denoted as La). After each met peg active length is reduced. Let's process queries separately: at each step we can find next peg with using binary search. If active length becomes at least two times shorter or current step is the first one we proceed to the next step. Otherwise say current peg is peg i and the next one is peg j (without loss of generality i < j). Then after peg j the rope will again touch peg i and the weight will again rotate around peg i. Indeed, 2(xj - xi) ≤ La so the weight will rotate around a peg not to the right to peg i. And either i = 1 or La ≤ xi - xi - 1 so it won't also rotate around a peg to the left to peg i. As long as La ≥ xj - xi the weight will rotate around these two pegs so we can skip through several steps momentarily. This way active length is shortened at least twice so there will be no more than logL steps.

Time: O(mlogLlogn); solution.

555E - Case of Computer Network

First of all, let's reduce this problem to a problem on a tree. In order to achieve this let's orient edges in all biconnected components according to a DFS-order. We'll get a strongly connected component. Suppose it's false. Then this component can be divided into parts A and B such that there's no edge from B to A. As initially there are at least two edges between A and B this situation is impossible because after entering B in our DFS we'll have to exit via one of these edges. Contradiction. We can compress all biconnected components.

Now we need to handle several queries "orient edges on a simple path in a tree" and to check if there are no conflicts. For this let's hang our tree and find LCA's for queries' pairs of vertices. Start another DFS and for every subtree count vertices in this subtree that are beginnings of queries' paths (call it a), that are ends of queries' paths (call it b) and that are precalculated LCAs (call it c). Now we can orient the edge connecting the root of the subtree and its parent: if a - c is positive then it should be oriented up, if b - c is positive then it should be oriented down, if both are positive there's no solution, if both are zeros the direction does not matter.

Time: O(n + qlq) where lq is the time of calculating LCA per query; solution that uses slightly other method for the last part.

#### History

Revisions

Rev. Lang. By When Δ Comment
ru15 Lord_F 2016-01-28 12:44:35 4 Мелкая правка: 'сделаем $max(#единиц,#' -> 'сделаем$min(#единиц,#'
ru14 Lord_F 2015-07-19 06:54:38 10 Мелкая правка: 'ntu.com/11788459/), исполь' -> 'ntu.com/11902227/), исполь'
en17 Lord_F 2015-07-19 06:54:27 10 Tiny change: 'ntu.com/11788459/) that us' -> 'ntu.com/11902227/) that us'
ru13 Lord_F 2015-06-29 21:07:43 2 Мелкая правка: 'елано $2n-m-2k+1$ опе' -> 'елано $2n-l-2k+1$ опе'
ru12 Lord_F 2015-06-29 16:27:01 28
en16 Lord_F 2015-06-29 16:26:01 2 Tiny change: ' $2n-k-2l+2$ operatio' -> ' $2n-k-2l+1$ operatio'
ru11 Lord_F 2015-06-29 16:25:30 12005
ru10 Lord_F 2015-06-29 15:41:36 35 Мелкая правка: 's shorter we procee' -> 's shorter _or current step is the first one_ we procee'
en15 Lord_F 2015-06-29 15:40:24 35 Tiny change: 's shorter we procee' -
ru9 Lord_F 2015-06-28 23:06:48 2 Мелкая правка: 'Time: $O(nl_q)$ wher' -> 'Time: $O(n+ql_q)$ wher'
en14 Lord_F 2015-06-28 23:05:55 2 Tiny change: 'Time: $O(nl_q)$ wher' -> 'Time: $O(n+ql_q)$ wher'
ru8 Lord_F 2015-06-28 19:02:24 314
en13 Lord_F 2015-06-28 19:01:34 314
ru7 Lord_F 2015-06-28 18:49:48 62
ru6 Lord_F 2015-06-28 18:49:31 1514
en12 Lord_F 2015-06-28 18:48:19 22
en11 Lord_F 2015-06-28 18:47:44 1476
en10 Lord_F 2015-06-28 18:05:08 1
en9 Lord_F 2015-06-28 18:04:19 1038
ru5 Lord_F 2015-06-28 18:02:54 1039
ru4 Lord_F 2015-06-28 17:25:21 3 Мелкая правка: 'es. $2n-k-l+1$ operatio' -> 'es. $2n-k-2l+2$ operatio'
en8 Lord_F 2015-06-28 17:25:01 3 Tiny change: 'es. $2n-k-l+1$ operatio' -> 'es. $2n-k-2l+2$ operatio'
en7 Lord_F 2015-06-28 17:23:45 271
ru3 Lord_F 2015-06-28 17:21:24 3567
en6 Lord_F 2015-06-28 16:56:11 636 Tiny change: 'ogq)$or$qlogq$; solutio' - ru2 Lord_F 2015-06-28 16:37:50 60 en5 Lord_F 2015-06-28 16:33:48 1080 en4 Lord_F 2015-06-28 15:58:49 657 en3 Lord_F 2015-06-28 15:34:14 12 Tiny change: '1$ output \t{Yes} else \t{No}. But thi' -> '1\$ output "Yes" else "No". But thi'
en2 Lord_F 2015-06-28 15:27:30 1038
ru1 Lord_F 2015-06-27 23:03:38 332 Первая редакция перевода на Русский
en1 Lord_F 2015-06-27 22:57:25 327 Initial revision (published)