QOJ.ac

QOJ

Type: Editorial

Status: Open

Posted by: JakovG

Posted at: 2026-07-13 00:33:31

Last updated: 2026-07-13 00:34:39

Back to Problem

New Editorial for Problem #14295

EJOI 2025 Day 1 Task Collecting Diamonds Analysis Diamonds โ€“ Analysis Problem: Cheng Zhong, Analysis: Iliyan Yordanov We are given a directed weighted graph. The condition that each vertex has at least one outgoing edge means there are no dead ends โ€“ there is always an edge to continue along. Unlike classic graph problems, which maximize the total sum of weights, here the comparison is based on lexicographic order. We have to find the sum of the first ๐พ edges on a lexicographically largest path (comparing the weights). At first glance, this might seem easier: a straightforward simulation appears sufficient; we begin the traversal at the starting vertex of the edge with the largest weight, and in each round, we choose the currently accessible edge with the largest weight. However, the situation is more complex because multiple edges may have the same weight, leading to frequent ties for the maximum. Therefore, if we rely solely on simulation, each decision may involve multiple tied maximums, resulting in exponential time complexity. Subtask 1 The small constraints allow a direct BFS-like approach for the solution. We perform a simulation where round 0 begins with all vertices active, and in each round, we select the currently accessible edges with the largest weight and store their endpoints for the next round. The answer is obtained by storing the sum of the weights for each round. Code: diamonds6.cpp Time complexity: ๐‘‚(๐‘ + ๐‘€๐พ). Memory complexity: ๐‘‚(๐‘ + ๐‘€๐พ). Subtask 2 It is easy to see that the exponential behavior of the previous approach is because in each round we unnecessarily repeat the same vertices multiple times. We can use a boolean array to flag the vertices that have already been added to the next round or alternatively store each roundโ€™s vertices in a boolean array (instead of an integer vector). Code: diamonds5.cpp Time complexity: ๐‘‚(๐พ(๐‘ + ๐‘€ )). Memory complexity: ๐‘‚(๐‘€ + ๐พ๐‘ ) or ๐‘‚(๐‘€ + ๐‘ ) if we only store previous and current round. 1 / 8 EJOI 2025 Day 1 Task Collecting Diamonds Analysis Subtask 3 This subtask is a major step toward the full solution because ๐พ is large. We can see that there is an optimal construction for the lexicographically largest path, since after sufficiently many rounds, some edges (and vertices) must repeat because they belong to the lexicographically largest sequence of weights among all possibilities. Lemma 1: There exists a lexicographically largest path that begins with a simple path (without duplicating vertices) and then repeats a simple cycle. go to proof If we know the optimal construction, it becomes a straightforward task to compute the answer. The sequence of weights starts with some numbers and then it becomes periodic. For greater ๐พ, we have to find the sum of the terms of a periodic sequence. There are two approaches for the task โ€“ one is by doing smarter simulation round by round and the other is by computing a dp to find the optimal decisions. Both approaches require a bound on the number of iterations. One can experimentally or intuitively find that this number of iterations is linear. In fact, two paths have identical sequences of weights for all rounds if and only if they have identical sequences of weights for the first 2๐‘ rounds. We will discuss this in detail in the next subtask. The first approach is a continuation of the idea in the previous subtasks. Letโ€™s consider we have made sufficiently many rounds (at least 2๐‘). This means the non-optimal paths considered initially have already been eliminated, and we are now repeating the cycles of the possible optimal constructions. However, it is not straightforward, since the optimal paths can still be continued non-optimally for a couple of rounds (and then eliminated), after that these non-optimal continuations reappear, and so on. We can see that the only certain thing is that the starting vertices of all remaining paths need to be part of an optimal construction, otherwise they would have been eliminated already. So for each (๐‘Ÿ, ๐‘ฃ), where ๐‘Ÿ is the round and ๐‘ฃ is the vertex, it is enough to store a (๐‘Ÿ โˆ’ 1, ๐‘ข) it came from (if there are multiple options, it is enough to store one). Then, after 2๐‘ rounds, we pick an arbitrary vertex, recover the path, and examine the starting part, which must be an optimal construction (a path and then a cycle). The other approach is to use dynamic programming ๐‘‘๐‘[๐‘Ÿ][๐‘ฃ] = the optimal sequence of weights starting from vertex ๐‘ฃ and having ๐‘Ÿ rounds (which is also the length of the sequence). Let ๐‘ค(๐‘ฃ, ๐‘ข) denote the weight of edge (๐‘ฃ, ๐‘ข). We have the following recursive relation: ๐‘‘๐‘[๐‘Ÿ][๐‘ฃ] = max lexicographically ๐‘ขโˆถ for all edges (๐‘ฃ,๐‘ข) {๐‘ค(๐‘ฃ, ๐‘ข), ๐‘‘๐‘[๐‘Ÿ โˆ’ 1][๐‘ข]}. As the constraints are smaller, we can compute the dp for sufficiently many rounds ๐‘… 2 / 8 EJOI 2025 Day 1 Task Collecting Diamonds Analysis (at least 2๐‘) fast enough without optimizations. We pick the optimal sequence from ๐‘‘๐‘[๐‘…][0], ๐‘‘๐‘[๐‘…][1], ..., ๐‘‘๐‘[๐‘…][๐‘ โˆ’ 1]. There are different ways how exactly we can find the answer. We can store additional information so we can find the vertices of the edges that form the optimal sequence and then find the optimal construction from the vertices. Another way, used in the implementations, is to use only the sequence of weights. For this ๐‘… needs to be at least 3๐‘. We know the first elements must come from the path of an optimal construction, so to identify the repeating cycle we temporarily ignore the first ๐‘ elements. As the length of the repeating cycle in the optimal construction is at most ๐‘, we can find any valid repeating cycle in the sequence of the last 2๐‘ elements. The only drawback with the second approach is the memory if we store directly the sequences in each state. We have to be more efficient here and store the sequences as linked lists so ๐‘‘๐‘[๐‘Ÿ][๐‘ฃ] is only the head element of the sequence, and that element is linked to some optimal (for ๐‘ฃ) ๐‘‘๐‘[๐‘Ÿ โˆ’ 1][๐‘ข]. First approach Second approach Code diamonds_iliyan_n2_mem.cpp diamonds4.cpp Time complexity ๐‘‚(๐‘๐‘€ ) ๐‘‚(๐‘2๐‘€ ) Memory complexity ๐‘‚(๐‘€ + ๐‘2 ) ๐‘‚(๐‘€ + ๐‘2 ) Subtask 4 The constraints for this subtask make the graph consist of a single cycle or multiple disconnected cycles. This subtask is given so that competitors can think more about the cycles and the needed rounds for comparison. We can find the optimal traversal by comparisons: โ€ข For two traversals in the same cycle, we only need to compare their results of the first ๐‘™๐‘’๐‘›๐‘”๐‘กโ„Ž(๐‘๐‘ฆ๐‘๐‘™๐‘’) rounds; โ€ข For two traversals in different cycles, we only need to compare their results of the first ๐‘™๐‘๐‘š(๐‘™๐‘’๐‘›๐‘”๐‘กโ„Ž(๐‘๐‘ฆ๐‘๐‘™๐‘’1 ), ๐‘™๐‘’๐‘›๐‘”๐‘กโ„Ž(๐‘๐‘ฆ๐‘๐‘™๐‘’2 )) rounds. Although not necessary for this subtask, we can use the following lemma, which shows that only a linear number of comparisons are needed for the second case. Lemma 2: If two periodic sequences with periods ๐‘ and ๐‘ž have the same first ๐‘ + ๐‘ž terms, then they are identical. go to proof There is an even stronger bound: it is enough to compare the first ๐‘ + ๐‘ž โˆ’ gcd(๐‘, ๐‘ž) terms but this is not needed for the task and does not change the complexity. The lemma tells us that we need approximately 2๐‘ rounds to compare any two cycles. In the general case 3 / 8 EJOI 2025 Day 1 Task Collecting Diamonds Analysis when the optimal construction starts with a path this would require approximately 3๐‘ rounds (additional ๐‘ to enter the cycle). But it is easy to see that still 2๐‘ rounds are enough because the cycle and the path have to be disjoint (they cannot share vertices). This is a tight bound as illustrated in the following example, where 2๐‘ โˆ’ 3 rounds are required to compare the two possible optimal constructions (there are also such tests with a modified version): 1 3 2 2 2 2 2 1 2 2...2 0 1 2 3 4 N-2 N-1 ... ... Code: diamonds9.cpp Time complexity: ๐‘‚(๐‘2 ). Memory complexity: ๐‘‚(๐‘ ). Subtask 5 The task becomes much simpler when all ๐‘‘[๐‘–] are distinct. There is only one maximum choice for each round, so the only challenge is handling large ๐พ. It is easy to see that the optimal construction is first a simple path and then repeating a simple cycle. So we follow the maximum weight for each round until we find a cycle, and then we have to find the sum of the terms of a periodic sequence. This subtask allows contestants to observe the optimal construction more easily. Code: diamonds_iliyan_unique_d.cpp Time complexity: ๐‘‚(๐‘ + ๐‘€ ). Memory complexity: ๐‘‚(๐‘ + ๐‘€ ). Subtask 6 This subtask is similar to the previous one as the optimal construction is much easier to see than in the general case. Let edge (๐‘ข, ๐‘ฃ) be the one with weight 2. We should use the weight 2 as often as possible. We have to start with (๐‘ข, ๐‘ฃ) and then return as quickly as possible (using the fewest number of weight-1 edges) to vertex ๐‘ข. If this is not possible, the answer is simply 2 + (๐พ โˆ’ 1) = ๐พ + 1. Otherwise we have to compute how many times we will use weight 2 and the answer is ๐พ+ this number. We can use BFS to find the shortest path of 1-s from ๐‘ฃ to ๐‘ข or determine that no such path exists. Code: diamonds8.cpp Time complexity: ๐‘‚(๐‘ + ๐‘€ ). Memory complexity: ๐‘‚(๐‘ + ๐‘€ ). 4 / 8 EJOI 2025 Day 1 Task Collecting Diamonds Analysis Subtask 7 We now revisit the two approaches and discuss the different ways to optimize them to fit the small memory constraint. There are two ways to optimize the first approach, which relied on smarter round-by-round simulation. We can use a bitset memory optimization. Instead of storing, for each (๐‘Ÿ, ๐‘ฃ), a (๐‘Ÿ โˆ’ 1, ๐‘ข) it came from, we can use one bitset per round to record the vertices that are present. If we know the vertices in consecutive rounds it is easy to find a path that starts from (0, ๐‘ฃ) and goes to (๐‘…, ๐‘ข) for some vertices ๐‘ฃ and ๐‘ข, and a final round ๐‘…. If we are at (๐‘–, ๐‘ฅ) and we have an edge (๐‘ฅ, ๐‘ฆ) in the original graph, we have to check if vertex ๐‘ฆ was present in the next round ๐‘– + 1, i.e. if (๐‘– + 1, ๐‘ฆ) existed during the simulation. Once we find a path, we can compute the answer as before. The second way to optimize the first approach uses the earlier idea of finding the answer using only the sequence of weights. We can store the maximum weight that is used for each round and construct the optimal sequence of weights without knowing the exact path. Then, as described earlier, we can find the cycle by examining the last 2๐‘ elements and then compute the final answer. (we still need at least 3๐‘ rounds of simulation) For the second approach, we will first optimize the time complexity. We recall the recursive relation: ๐‘‘๐‘[๐‘Ÿ][๐‘ฃ] = max lexicographically ๐‘ขโˆถ for all edges (๐‘ฃ,๐‘ข) {๐‘ค(๐‘ฃ, ๐‘ข), ๐‘‘๐‘[๐‘Ÿ โˆ’ 1][๐‘ข]}. The bottleneck is the โ€max lexicographicallyโ€ comparison, which we previously did in linear time, but this can be improved. We will keep a sorted list of ๐‘‘๐‘[๐‘Ÿ โˆ’ 1][๐‘ฃ] (for fixed ๐‘Ÿ โˆ’ 1) and we need to obtain a sorted list of ๐‘‘๐‘[๐‘Ÿ][๐‘ฃ]. For this we can store in ๐‘‘๐‘[๐‘Ÿ โˆ’ 1][๐‘ฃ] โ€ranksโ€ which are numbers that show the relative order of the weight sequences. To obtain the sorted list of ๐‘‘๐‘[๐‘Ÿ][๐‘ฃ], for each ๐‘ฃ we use ๐‘ค(๐‘ฃ, ๐‘ข) as a primary key and ๐‘‘๐‘[๐‘Ÿ โˆ’ 1][๐‘ข] as a secondary key, where ๐‘ข is the argmax in the relation above for ๐‘ฃ. Then we sort these pairs lexicographically and find the new ranks for ๐‘‘๐‘[๐‘Ÿ][๐‘ฃ]. We can even do this in linear time as we can do a radix sort over the pairs. It is also possible not to fix the number of iterations and terminate when the ranks stop changing. Now we have good time complexity and we will find the optimal construction in the following way. Suppose we have all ๐‘‘๐‘[๐‘…][๐‘ฃ] for some number of rounds ๐‘…, and we construct a new graph with the edges (๐‘ฃ, ๐‘ข) for each ๐‘ฃ, where ๐‘ข is the argmax in the dp relation for ๐‘‘๐‘[๐‘…][๐‘ฃ]. We claim that if ๐‘… is at least 2๐‘ and we start from the optimal ๐‘ฃ (with the highest rank ๐‘‘๐‘[๐‘…][๐‘ฃ]), and follow these edges, we will find an optimal construction. This is because all paths with such length starting from ๐‘ฃ must follow an optimal construction so even if there are ties for argmax for ๐‘ฃ, all of them will be part of optimal constructions. A similar argument holds for the other vertices we visit along the path since non-optimal possibilities would be eliminated for large enough ๐‘…. Thus, we directly obtain the optimal 5 / 8 EJOI 2025 Day 1 Task Collecting Diamonds Analysis construction, from which the answer follows as before. For this solution, ๐‘… = ๐‘ is also sufficient, since the dp takes a more global view and removes non-optimal possibilities from the beginning, and needs additional iterations to propagate that information. First approach Second approach Code diamonds_encho_bitset.cpp, diamonds7.cpp diamonds1.cpp, diamonds_iliyan.cpp Time complexity ๐‘‚(๐‘๐‘€ ) ๐‘‚(๐‘๐‘€ + ๐‘2 log ๐‘ ) or ๐‘‚(๐‘๐‘€ + ๐‘2 ) Memory complexity ๐‘‚ (๐‘€ + ๐‘2 64 ) for the bitset and ๐‘‚(๐‘ + ๐‘€ ) for the other solutions ๐‘‚(๐‘ + ๐‘€ ) Final thoughts During testing, we found a particular variation of the first approach. Instead of reasoning about the number of rounds, we can terminate if we repeat the same set of vertices during a round (which we can find using hashing). Then the cycle is the sequence of weights between the two repetitions. It turns out exponentially many rounds may be required for the repetition to happen so we still require a bound for the rounds. The best type of test we came up with to battle such cheat solutions is the following: 3 3 3 1 2 1 2 1 2 1 2 1 2 1 2 0 1 2 3 4 5 6 7 8 9 10 12 11 The base model is we have some constant ๐‘˜ and then we make cycles of lengths ๐‘˜, 2๐‘˜, 3๐‘˜, 5๐‘˜, 7๐‘˜, 11๐‘˜, โ€ฆ that repeat 1, 2, โ€ฆ , ๐‘˜ as weights (in the example ๐‘˜ = 2 and the cycles are of lengths 2, 4 and 6). In this way we need the LCM of the lengths (a huge value), as the number of rounds required to repeat the same set of vertices. Also if we terminate early, it is not simple to compute the answer looking at the sequence of weights, since we still have a non-trivial repeating cycle (the simplest correct way is to have a full solution like diamonds7.cpp). Unfortunately, it turned out we had missed adding these tests in the official test data so a few contestants passed by terminating early and computing the answer in a wrong way. The original proposal for this task was even harder, but we believe the current variant is more appropriate for EJOI. In fact, it turned out to be slightly harder for contestants than we initially thought. 6 / 8 EJOI 2025 Day 1 Task Collecting Diamonds Analysis Proof of Lemma 1 Lemma 1: There exists a lexicographically largest path that begins with a simple path and then repeats a simple cycle. Suppose a lexicographically largest path is: ๐ฟ โˆถ= (๐‘ฃ0 , ๐‘ฃ1 ), (๐‘ฃ1 , ๐‘ฃ2 ), โ€ฆ . As the path is infinite and the different vertices are only ๐‘, there has to be a repeated vertex. Let the first repeated vertex be ๐‘ฃ๐‘— , with its previous occurrence at ๐‘ฃ๐‘– (0 โ‰ค ๐‘– < ๐‘—). This also means that ๐‘ฃ0 , ๐‘ฃ1 , โ€ฆ , ๐‘ฃ๐‘–โˆ’1 is a simple path and ๐‘ฃ๐‘– , ๐‘ฃ๐‘–+1, โ€ฆ , ๐‘ฃ๐‘—โˆ’1, ๐‘ฃ๐‘– (๐‘ฃ๐‘– = ๐‘ฃ๐‘— ) is a simple cycle. Let ๐‘ƒ โˆถ= (๐‘ฃ0 , ๐‘ฃ1 ), (๐‘ฃ1 , ๐‘ฃ2 ), โ€ฆ , (๐‘ฃ๐‘–โˆ’1, ๐‘ฃ๐‘– ) and ๐ถ โˆถ= (๐‘ฃ๐‘– , ๐‘ฃ๐‘–+1), (๐‘ฃ๐‘–+1, ๐‘ฃ๐‘–+2) โ€ฆ , (๐‘ฃ๐‘—โˆ’2, ๐‘ฃ๐‘—โˆ’1), (๐‘ฃ๐‘—โˆ’1, ๐‘ฃ๐‘– ). We will prove the following claim by induction: for each ๐‘Ÿ โ‰ฅ 1, the sequence of weights in ๐ฟ starts with the sequence of weights of {๐‘ƒ , ๐ถ(๐‘Ÿ)}, where ๐ถ (๐‘Ÿ) denotes ๐ถ, โ€ฆ , ๐ถ โŸ๐‘Ÿ . Base case ๐‘Ÿ = 1. We know that the path ๐ฟ starts with {๐‘ƒ , ๐ถ} so the claim holds. Induction step. Let the claim be true for some ๐‘Ÿ โ‰ฅ 1. We will prove it for ๐‘Ÿ + 1. The claim is true for ๐‘Ÿ, so the weights of ๐ฟ start with the weights of {๐‘ƒ , ๐ถ(๐‘Ÿ)}, and we will denote the edges after that with ๐‘†. We will also denote ๐‘ƒ โ€ฒ โˆถ= {๐ถ, ๐‘†}. The sequence of weights of ๐ฟ equals that of {๐‘ƒ , ๐ถ(๐‘Ÿโˆ’1), ๐‘ƒโ€ฒ}. Since {๐‘ƒ , ๐ถ(๐‘Ÿโˆ’1), ๐‘†} is a valid path (with one fewer cycle), ๐‘ƒ โ€ฒ must be lexicographically larger than or equal to ๐‘†. If they are equal, then we are ready as this would mean that the weights of ๐‘† are starting with the weights of ๐ถ (since ๐‘ƒ โ€ฒ = {๐ถ, ๐‘†}), so ๐‘ƒ โ€ฒ is starting with weights ๐ถ (2) and ๐ฟ is starting with weights {๐‘ƒ , ๐ถ(๐‘Ÿ+1)}. Letโ€™s assume they are not equal. So there must be an edge in ๐‘ƒ โ€ฒ with larger weight than the corresponding one in ๐‘†. Let the first such edge be ๐‘’. If ๐‘’ is in the cycle ๐ถ, then the cycle will be lexicographically larger than the corresponding part of ๐‘†, so a path {๐‘ƒ , ๐ถ(๐‘Ÿ+1)} will be lexicographically larger than ๐ฟ, which is a contradiction. The only remaining case is when ๐‘’ is after the cycle ๐ถ. This would mean that the sequence of weights in the cycle ๐ถ is the same as the corresponding sequence of weights in ๐‘†, which means that the weights of ๐‘† are starting with the weights of ๐ถ, and ๐ฟ is starting with weights {๐‘ƒ , ๐ถ(๐‘Ÿ+1)}. Thus, the claim follows by induction. This means that the sequence of weights in ๐ฟ is the same as the sequence of weights of {๐‘ƒ , ๐ถ, ๐ถ, โ€ฆ }. Since {๐‘ƒ , ๐ถ, ๐ถ, โ€ฆ } is a valid path, it is a lexicographically largest path that begins with a simple path and then repeats a simple cycle. 7 / 8 EJOI 2025 Day 1 Task Collecting Diamonds Analysis Proof of Lemma 2 Lemma 2: If two periodic sequences with periods ๐‘ and ๐‘ž have the same first ๐‘ + ๐‘ž terms, then they are identical. Without loss of generality, assume ๐‘ โ‰ค ๐‘ž. Let the sequences be ๐‘ƒ0 , ๐‘ƒ1 , โ€ฆ and ๐‘„0 , ๐‘„1 , โ€ฆ We will prove the following claim by induction: for each ๐‘Ÿ โ‰ฅ 0, the sequences have the same first ๐‘ + ๐‘ž + ๐‘Ÿ๐‘ terms. Base case ๐‘Ÿ = 0. As the sequences have the same first ๐‘ + ๐‘ž terms, the claim holds. Induction step. Let the claim be true for some ๐‘Ÿ โ‰ฅ 0. We will prove it for ๐‘Ÿ + 1. Letโ€™s assume the contrary and let ๐‘ + ๐‘ž + ๐‘Ÿ๐‘ โ‰ค ๐‘– < ๐‘ + ๐‘ž + (๐‘Ÿ + 1)๐‘ be an index such that ๐‘ƒ๐‘– โ‰  ๐‘„๐‘– . We have the following: โ€ข As ๐‘ƒ has a period ๐‘, we have ๐‘ƒ๐‘– = ๐‘ƒ๐‘–โˆ’๐‘. โ€ข As ๐‘– โˆ’ ๐‘ < ๐‘ + ๐‘ž + ๐‘Ÿ๐‘, we have ๐‘ƒ๐‘–โˆ’๐‘ = ๐‘„๐‘–โˆ’๐‘. โ€ข As ๐‘„ has a period ๐‘ž, we have ๐‘„๐‘–โˆ’๐‘ = ๐‘„๐‘–โˆ’๐‘โˆ’๐‘ž. โ€ข So, ๐‘ƒ๐‘– = ๐‘ƒ๐‘–โˆ’๐‘ = ๐‘„๐‘–โˆ’๐‘ = ๐‘„๐‘–โˆ’๐‘โˆ’๐‘ž. Similarly, ๐‘„๐‘– = ๐‘„๐‘–โˆ’๐‘ž = ๐‘ƒ๐‘–โˆ’๐‘ž = ๐‘ƒ๐‘–โˆ’๐‘โˆ’๐‘ž (since ๐‘ โ‰ค ๐‘ž, we have ๐‘– โˆ’ ๐‘ž โ‰ค ๐‘– โˆ’ ๐‘ < ๐‘ + ๐‘ž + ๐‘Ÿ๐‘). But 0 โ‰ค ๐‘– โˆ’ ๐‘ โˆ’ ๐‘ž < ๐‘ + ๐‘ž + ๐‘Ÿ๐‘, so ๐‘ƒ๐‘–โˆ’๐‘โˆ’๐‘ž = ๐‘„๐‘–โˆ’๐‘โˆ’๐‘ž by the induction step and this means ๐‘ƒ๐‘– = ๐‘„๐‘– , which is a contradiction. Thus, the claim follows by induction. This means that the sequences must be identical, since we can pick an arbitrarily large ๐‘Ÿ. 8 / 8

Comments

No comments yet.