Codeforces round #396 editorial

Revision en8, by mohammedehab2002, 2017-02-07 15:31:04

[problem:A]

If the strings are the same, Any subsequence of a is indeed a subsequence of b so the answer is "-1", otherwise the longer string can't be a subsequence of the other (if they are equal in length and aren't the same, No one can be a subsequence of the other) so the answer is maximum of their sizes.

Time complexity : O(|a| + |b|).

Problem author : me.

Solution author : me.

Testers : me and mahmoudbadawy.

[problem:B]

First solution:-

Let x, y and z be the lengths of 3 line segments such that x ≤ y ≤ z, If they can't form a non=degenerate triangle, Line segments of lengths x - 1, y and z or x, y and z + 1 can't form a triangle, So we don't need to try all the combinations, If we try y as the middle one, We need to try the maximum x that is less than or equal to y and the minimum z that is greater than y, The easiest way to do so is to sort the line segments and try every consecutive 3.

Time complexity : O(nlog(n)).

Second solution:-

Depending on the note from the first solution, If we try to generate a sequence such that after sorting every consecutive 3 line segments will form a degenerate triangle, It will be 1 1 2 3 5 8 13 ... which is Fibonacci sequence, Fibonacci is a fast growing sequence, fib(45) = 1134903170, Notice that Fibonacci makes maximum n with "NO" as the answer, That means the answer is indeed "YES" for n ≥ 45, For n < 45, You can do the naive O(n3) solution or the first solution.

let x be the number that satisfies these inequalities:-

fib(x) ≤ maxAi.

fib(x + 1) > maxAi.

Time complexity : O(x3) or O(xlog(x)).

Problem author : me.

Solutions author : me.

Tester : me and mahmoudbadawy.

[problem:C]

Let dp[i] be the number of ways to split the prefix of s ending at index i into substrings that fulfills the conditions. Let it be 0-indexed. Our base case is dp[0] = 1. Our answer is dp[n - 1]. Now let's calculate it for every i. Let l be the minimum possible index such that the substring from l to i satisfies the condition, Let x be a moving pointer, At the beginning x = i - 1, every time we move x we calculate new l depending on the current character like that l = max(l, i - as[x]). While x is greater than or equal to l we add dp[x] to dp[i], To find the longest substring find maximum i - l, To find the minimum number of substrings, there is an easy greedy solution, Find the longest valid prefix and delete it and do the same again until the string is empty, The number of times this operation is repeated is our answer.

Time complexity : O(n2).

Try to find O(n) solution(I'll post a hard version of some problems on this blog soon).

Problem authors : me and mahmoudbadawy.

Solution author : me and mahmoudbadawy.

Testers : me and mahmoudbadawy.

[problem:D]

I consider union-find O(1) in my complexity analysis.

Online solution:-

Let's build a union-find data structure but with a little difference, We will add weights on the edges linking words, 0 if they are equal and 1 if they are opposites, The xor of the path between 2 words is the relation between them. See the code for better understanding.

Offline solution:-

Let's build a graph containing words, For every relation in the input add a new edge with the weight of 0 if they are equal and 1 if they are opposites, If adding the edge doesn't make the graph cyclic, Our relation is valid, Otherwise it may be valid or invalid. Check if adding that edge will make the graph cyclic or not using union-find like Kruskal's algorithm. Suspend answering relations that will make the graph cyclic, Now we have a forest of trees, Let cum[i] be the xor of the weights on the edges in the path from the root of the component of node i to node i. To find the relation between 2 words u and v, Check if they are in the same component using union-find, If they aren't the answer is 3 otherwise the answer is , Now to answer suspended relations, Find the relation between the 2 words and check if it's the same as the input relation, Then answer the queries.

Time complexity for both solutions : O((n + m + q)log(n) * maxL) where maxL is the length of the longest string.

Problem author : mahmoudbadawy.

Online solution author : Codeforces tester.

Offline solution author : me.

[problem:E]

If we have an array ans[i] which represents the number of paths that makes the ith bit sit to 1, Our answer is the sum of ans[i] * 2i for all i less than or equal to log(n). Now let's calculate this array.

Let arr[i][x] be the binary value of the xth bit of the number attached to node i(just to make work easier). Let dp[i][x][j] be the number of paths starting from node i and ends at some node of the subtree of node i that makes the xth bit of the xor sit to j. Our base case is the paths starting from the node and ending at the same node so for any i and x, dp[i][x][arr[i][x]] = 1. The path starting from node a to node b such that a ≠ b is the path starting from the child of a that is an ancestor of b with node a added to it so we can calculate our dp like that:-

Root the tree at node 1 and dfs, Let the current node be i, dp[i][x][j] +  = dp[k][x][jarr[i][x]] where k loops on the children of i. Add dp[i][x][1] to ans[x]. Now that we have our dp, The naive way to complete the solution is to try every path with node i as the lca with this dp by looping over every 2 different children of node i but with some math you can realize that:-

Let s[i][x][j] be the sum of dp[k][x][j] where k loops over the children of node i.

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en24 English mohammedehab2002 2017-02-07 22:52:00 0 (published)
en23 English mohammedehab2002 2017-02-07 22:50:50 44
en22 English mohammedehab2002 2017-02-07 22:44:01 153
en21 English mohammedehab2002 2017-02-07 19:09:17 64
en20 English mohammedehab2002 2017-02-07 19:01:28 3
en19 English mohammedehab2002 2017-02-07 18:56:55 1053
en18 English mohammedehab2002 2017-02-07 18:40:41 139
en17 English mohammedehab2002 2017-02-07 18:05:35 108
en16 English mohammedehab2002 2017-02-07 17:43:14 499
en15 English mohammedehab2002 2017-02-07 16:58:30 3 Tiny change: 'y to find $O(n)$ so' -> 'y to find an $O(n)$ so'
en14 English mohammedehab2002 2017-02-07 16:56:23 61
en13 English mohammedehab2002 2017-02-07 16:47:14 11
en12 English mohammedehab2002 2017-02-07 16:37:58 52
en11 English mohammedehab2002 2017-02-07 16:23:20 21
en10 English mohammedehab2002 2017-02-07 16:18:49 8
en9 English mohammedehab2002 2017-02-07 16:05:25 52
en8 English mohammedehab2002 2017-02-07 15:31:04 2931
en7 English mohammedehab2002 2017-02-07 03:21:31 36 Tiny change: 'uthor : me.\n\nTeste' -> 'uthor : me and [user:mahmoudbadawy].\n\nTeste'
en6 English mohammedehab2002 2017-02-07 03:06:58 2 Tiny change: 'l=max(l,i-{a_s[x]})$. W' -> 'l=max(l,i-a_{s[x]})$. W'
en5 English mohammedehab2002 2017-02-07 03:05:28 2 Tiny change: 'l=max(l,i-a_s[x])$. While ' -> 'l=max(l,i-{a_s[x]})$. While '
en4 English mohammedehab2002 2017-02-07 03:04:46 1 Tiny change: ',i-a_s[x]). While $x' -> ',i-a_s[x])$. While $x'
en3 English mohammedehab2002 2017-02-07 03:03:41 54
en2 English mohammedehab2002 2017-02-07 03:00:50 87
en1 English mohammedehab2002 2017-02-07 02:52:07 2956 Initial revision (saved to drafts)