Yandex Algorithm Round 2.2 problems analysis

Правка en4, от GlebsHP, 2015-06-14 10:38:39

Good evening Codeforces, let me briefly describe solutions for all problems of today's morning yandex algorithm round. Thanks everyone who participated, I apologize for making problems a bit too tough and viscous for a 100 minutes contest. Anyway, I hope everyone found something interesting.

I would like to thank lperovskaya for organising this competition and managing Yandex.contest, snarknews and SergeiFedorov for their help with the problemset, Endagorion, PavelKunyavskiy, AleX, glebushka98, gustokashin, map and boris for testing. Special thanks to Gassa and my girlfriend Marina Kruglikova for fixing mistakes and disambiguations in English and Russian statements.

Let's get it started.

Problem A. Odysseus Sails Home.

There is no tricky idea behind this problem: one just needs to check if the vector (xf - xs, yf - ys) can be represented as a convex combination of vectors (xi, yi). One of the easiest approaches for the general case is to try all pairs of wind vectors and check if the target vector lies inside the cone they form. However, the devil is in the details. One shouldn't forget to:

  • Check if it's possible to get to Ithaca using only one wind direction;

  • Special if for case (xf, yf) = (xs, ys);

  • Ignore wind vectors (xi, yi) = (0, 0);

  • Avoid usage of doubles — everything fits in long long.

Time complexity: O(n2). O(nlogn) solution already exists.

Problem B. Chariot Racing.

For the fixed value t = const we can easily calculate the intersection of all segments (chariots) as max(0, min(bi + vi * t) - max(ai + vi * t)). The problem was to find maximum for t ≥ 0.

Both min(bi + vi * t) and max(ai + vi * t) are convex functions. min(bi + vi * t) is concave upward, because it's derivative only decreases, as faster chariots overtake slower one. Similar max(ai + vi * t) is convex down. This means function min(bi + vi * t) - max(ai + vi * t) is concave upward, and this, in turn is sufficient condition for applying ternary search.

Ternary search is enough to solve the problem, but the solution which does binary search on derivative is faster and more stable. We need to find the maximum t such that the chariot i with minimum bi + vi * t goes faster then the chariot j with maximum aj + vj * t.

The only special case (for some solutions only) was n = 1.

Time complexity: O(nlogMaxC).

Problem C. Equality and Roads.

First check if the graph is connected. If no, print <<\t{NO}>> for all queries.

For connected graph count the number of connected components if only 0-edges are allowed (denote it as a) and the number of connected components if only 1-edges are allowed (denote it as b). Then, for the given x it's possible to construct the desired span if and only if condition b - 1 ≤ x ≤ n - 1 - a holds.

Lets proof the above statement. It's pretty obvious that this condition is necessary, but the sufficiensy isn't that clear. In my opinion, the easiest way is to present the algorithm. It consists of five steps:

  1. Create DSU, add all 1-edges.

  2. Add all 0-edges, remember which of them caused joins. There will be b - 1 such edges.

  3. Clear the DSU, add all 0-edges remembered on step 2.

  4. Add 0-edges until there are exactly x of them in the current span.

  5. Add 1-edges until the graphs becomes connected. That will always happen because of the step 1 and 2.

Time complexity: O(n).

Problem D. Sequences of Triangles.

Thanks to snarknews — the author and developer of this problem.

Let f(x) be the longest sequence that ends on the triangle with the hypotenuse of length x. If we generate all Pithagorean triples with a, b, c ≤ L the dynamic programming approach will be the one that is easy to implement here.

Exhaustive description of the generation process and Euclid's formula could be found here, I would like to skip copying it to analysis.

Problem E. Strong Squad.

Thanks to SergeiFedorov — the author of this problem.

Perimeter p is equal to 2·(h + w), where h is the number of rows and w is the number of columns in the resulting rectangle. Build a bipartite graph on rows and columns where there is an edge connecting row x to column y if and only if soldier(x, y) = 0. What we should find now is the maximum independent set, such that in both set of rows and set of columns there is a least one vertex chosen (we are not allowed to choose rectangles

Unable to parse markup [type=CF_TEX]

).

The [well-known fact](https://en.wikipedia.org/wiki/K%C3%B6nig%27s_theorem_(graph_theory)) (yes, just say that the fact is well-known if you don't want to proove it) is that the size of the maximum independent subset in bipartite graph is equal to |V| + |U| - ν(G), where ν(G) stands for the maximum matching. To meet the condition that there should be at least one vertex chosen in both parts we should:

  1. Try all the available pairs;

  2. Exclude vertices already connected to chosen pair;

  3. Find maximum matching.

Time complexity: O((nm)2·min(n, m)) or O(n5) for the worst case n = m. Is reduced to O(n4.5) by using Dinic's algorithm.

About Time Limit: though for n = m = 100 the number of operations will be about C·1010, C seems to be pretty small. We can show that

Unable to parse markup [type=CF_TEX]

comes from the fact that the worst case is then only half of the cells is filled with zeroes. Also at least

Unable to parse markup [type=CF_TEX]

comes from the Kuhn's algorithm itself. The actual timing for the most straightforward Kuhn was about 2.5 second from 5 seconds TL. Any optimisations sped it up to less than 1 second.

Problem F. Lexicographically Smallest String.

Теги yandex.algorithm, analysis

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en20 Английский GlebsHP 2015-06-22 19:44:36 4 Tiny change: ' \leq n - 1 - a$ hold' -> ' \leq n - a$ hold'
en19 Английский GlebsHP 2015-06-18 22:03:21 0 (published)
en18 Английский GlebsHP 2015-06-16 04:36:28 0 Tiny change: '(S) < c + $Answer(S')' -> '(S) < c + Answer(S')'
en17 Английский GlebsHP 2015-06-16 04:36:04 6 Tiny change: '(S) < c + $Answer(S')' -> '(S) < c + Answer(S')'
en16 Английский GlebsHP 2015-06-16 04:35:01 1 Tiny change: '(S) < c + $Answer(S')' -> '(S) < c + Answer(S')'
en15 Английский GlebsHP 2015-06-16 04:32:18 6 Tiny change: '(S) < c + $Answer(S')' -> '(S) < c + Answer(S')'
en14 Английский GlebsHP 2015-06-16 04:30:28 4 Tiny change: '(S) < c + $Answer(S')' -> '(S) < c + Answer(S')'
en13 Английский GlebsHP 2015-06-16 04:28:49 1 Tiny change: '(S) < c + $Answer(S')' -> '(S) < c + Answer(S')'
en12 Английский GlebsHP 2015-06-16 04:27:51 3551 (saved to drafts)
en11 Английский GlebsHP 2015-06-14 10:57:57 0 (published)
en10 Английский GlebsHP 2015-06-14 10:53:58 0 Tiny change: 'ity: $O(n log MaxC)' -> 'ity: $O(n \cdot log MaxC)'
en9 Английский GlebsHP 2015-06-14 10:53:20 7 Tiny change: 'ity: $O(n log MaxC)' -> 'ity: $O(n \cdot log MaxC)'
en8 Английский GlebsHP 2015-06-14 10:52:20 6 Tiny change: 'ity: $O(n log MaxC)' -> 'ity: $O(n \cdot log MaxC)'
en7 Английский GlebsHP 2015-06-14 10:51:48 6 Tiny change: 'ity: $O(n log MaxC)' -> 'ity: $O(n \cdot log MaxC)'
en6 Английский GlebsHP 2015-06-14 10:51:06 16
en5 Английский GlebsHP 2015-06-14 10:48:33 127
en4 Английский GlebsHP 2015-06-14 10:38:39 1957
en3 Английский GlebsHP 2015-06-14 00:07:24 116
en2 Английский GlebsHP 2015-06-14 00:00:05 1306
en1 Английский GlebsHP 2015-06-13 23:11:17 2786 Initial revision (saved to drafts)