Блог пользователя onufryw

Автор onufryw, история, 5 месяцев назад, По-английски

The International Collegiate Programming Contest is seeking original programming problems for the 2026 ICPC Finals contest. The location and exact date are still unannounced, but the ICPC Finals are anticipated to take place in the fourth quarter of 2026.

All problems must be submitted by Saturday, January 31, 2026.

A problem submission must include at least:

  • a problem statement that includes at least one illustrative test case and its corresponding output
  • a brief description of the algorithm used in the solution along with an estimate of the difficulty of the problem
  • a solution in C++, Java, Python, or Kotlin

Additional materials such as test data and test input validators are welcome. There's also a “Guide for Judges and Problem Contributors” provides further information about what a problem candidate should look like, reach out to me if interested in getting it (I have no idea how to attach a PDF to a CodeForces blogpost, if it's at all possible).

Please note that problems should generally not have been discussed or shown to other people. In the exceptional case when a problem is known to others than the submitter, this needs to be clearly stated in the submission (including the names and roles of those who have seen the problem).

Problems must be sent encrypted using the public key at the end and sent to problems@icpc.global. If you are unable to use PGP, or if you have any questions about problem candidates, please contact us through that address.

You must submit at least two problems for them to be considered. If you have not been an ICPC Finals judge before, attach your public PGP key and a short description of your competitive programming experience to your submission. Active ICPC contestants and coaches are ineligible to submit problems to the ICPC Finals contest.

You will receive a confirmation email for your submission. If you do not get one within a week, contact us. All submissions will be evaluated by the Selection Committee by the end of April 2026, so you will receive information about whether your problem was selected in May 2026.

If your problem is selected, you will be asked to be a judge for the 2026 Finals contest, which in particular means taking responsibility for the preparation of one of the other problems (not the one you authored), as well as participating in the preparation of the overall set. You will also be eligible to attend the World Finals. If you want to submit any of your rejected problems to a different contest (ICPC or non-ICPC), please ensure it’s a contest in which none of the Selection Committee members will participate (contact us if in doubt). The Selection Committee members are Jo Perry, John Bonomo, Derek Kisman, Gennady Korotkevich, Martin Kacer, Onufry Wojtaszczyk, Per Austrin, and Yujie An.

Thank you! ICPC Finals Selection Committee problems@icpc.global

PS: Please forward this message to anyone who is interested.

PPS: The PGP key:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: GPGTools — https://gpgtools.org

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
nkdF2LWJO7c23z+jdg==
=f9vw
-----END PGP PUBLIC KEY BLOCK-----

Полный текст и комментарии »

  • Проголосовать: нравится
  • +93
  • Проголосовать: не нравится

Автор onufryw, история, 7 месяцев назад, По-английски

In a few places I mentioned that besides the "standard" approaches to G (including the actual solution at the WF), there's a more geometric approach. Let me describe it here.

First, a recap of the problem. We're given a rectangular area with a triangulation, with up to 50K vertices. Each of the triangulation vertices has a distinct height, and the height within triangles is linearly interpolated. We're asked to find the length of the shortest path from the east edge of the rectangle to the west that all lies on one height. Additionally, there are no triangulation vertices (except corners) on the east and west edges.

First (this is common to both solutions), let's look at the set of points at a given height H. The intersection of this set with any triangle is either empty, a single vertex (the unique vertex of height H), or an interval. So, the set of points at height H forms a set of paths (which interesect triangulation triangles at intervals), and these paths can terminate by:

  • being a cycle (which is not interesting, as a cycle can't touch both the west and east edge of the rectangle)
  • one or both ends of such a path can be in the unique vertex of height H
  • one or both ends of such a path can reach one of the four edges of the rectangle.

Also, note that if we shift H a bit (without crossing the height of any triangulation vertex), then the length of the intersection of the path with any triangulation triangle is a linear function of H, and so the length of a whole path is a linear function of H. This implies, in particular, that the function "height to length of shortest path" is piecewise linear; and that the minimum length of a path is attained by a path that goes through a triangulation vertex.

The non-geometric solution at this point sweeps by height, and uses some data structure to keep track of the chains of paths and their lengths. I'll not describe this. Instead, I'll describe a more geometric solution.

First, let's do a quadratic solution (which is too slow). We can just run a tree search from the east edge at each candidate height, trying to reach the west edge. Each such tree search visits every triangle at most once, so it's linear (assuming we first precalculate for each triangle the triangles adjacent to it), so the whole thing is quadratic. Now, we'll improve on this.

We will try to run the tree search in "batch mode", processing multiple heights in one step. So, we'll maintain a piecewise linear function (by holding two range trees, one for the linear coefficient, and one for the constant) mapping height to length of path thus far. We begin at the east edge, and the function is constant zero. Now, there's a single triangulation triangle touching the east edge, call it ABC, with A and B being on the east edge. To avoid analysing the corners of the rectangle, we can run a tree search from A and from B to begin with.

Assume first h(C) > h(B) > h(A) (where h(P) denotes the height of point P). Then all the paths from the east edge (with the possible exception of the path through B, which we already handled) go through this triangle and hit edge AC (because the whole edge BC is higher than anything in the interior of AB). So, we can add the appropriate linear function to our range tree, and now go to process the edge AC, or rather, the unique triangle on the other side of AC. The case where h(C) is the smallest is symmetrical.

The other case is when, say, h(B) > h(C) > h(A). Then some of the paths go to the edge BC, some go to CA, and there's the path that goes at height h(C) which hits vertex C, and might do all sorts of things from there (because there might be a large number of paths at height C leaving that vertex). So, our tree search branches — it has to search the triangle on the other side of BC, the triangle on the other side of CA, and then also follow all the paths going out from C.

So, what's the time complexity on this? It's actually almost OK. If only these three branches (through BC, through CA, and through C) didn't visit the same triangles, we'd be fine — because then the whole tree search would visit each triangle at most once, and so the complexity would be O(N log N), with the log for maintaining the range trees. Alas, the world is not that great. Can the search through BC and the search through CA visit the same triangle? Yes, they can. The easy example is if there is only one path at height h(C) leaving C (and going to the west edge), through some triangle CDE. Then both the tree search through BC and the tree search through CA will visit triangle CDE, for height C+eps and C-eps, respectively. And if that happens repeatedly (and it can, we have testcases like this), this will make the whole thing quadratic.

We need to deal with this. In the specific case that we described, the way to deal with this is simply to follow one branch of the tree search (say, the one through BC), until it hits triangle CDE. Then pause that branch (having updated the height-to-path-length function for the heights in range, say, (h(C), h(D))), and switch to the branch through CA. Once that branch also hits CDE, having updated the function for, say, (h(E), h(C)), we can simply continue out of CDE through edge DE, for the whole range of heights (h(E), h(D)) — note that for height h(C) we don't need to update the function at all, whatever the cost of getting to C was at triangle ABC is accurate.

The more general case can be more complex — there could be multiple paths leading out of C, but some of them might cycle back to C again. A key observation is that if there are at least two paths out of C that hit some boundary of the rectangle (not counting the one through which we came in), then these two paths are triangle-disjoint (that is, they don't pass through the same triangles); and they also fully separate the AB-branch of the tree search, from the BC-branch. So, the only case we need to handle is the case where there is exactly one path out of C hitting the boundary, plus possibly some cycles.

The problem is that we need to detect this without actually traversing this path that goes to the boundary (because that path might be of length O(N), and we might need to do this detection O(N) times). Notice that, not counting the path we came in through, there's an odd number of paths going out of C, because the paths alternate between "higher on the left, lower on the right" and "higher on the right, lower on the left". So, what we actually do is we order these outgoing paths in a clockwise order, and traverse the second one (or any even-indexed one). It either cycles (in which case we remove both the exits from C that compose the cycle, we can also remove anything in the middle, as that has to be smaller cycles enclosed in the cycle we just found), or it hits the boundary. If it hits the boundary, then there has to be a path to the left of it that hits the boundary (because there's an odd number of paths to the left, so they can't all pair up in cycles), and a path to the right that hits the boundary. That means that:

  • the tree searches through BC and CA are triangle-disjoint
  • and they're also all triangle-disjoint from the path that we just traversed

So, to recap — we will advance the tree search triangle by triangle. We'll have some triangles marked as "stoppers" (this is the triangle CDE, above), which have to be reached twice in order for the search to proceed. If we enter a triangle, then:

  • if it's a stopper, and it hasn't been reached yet, we remove the "stopper" mark from it, and terminate this branch.
  • if we entered through an edge AB, and the height of the third point C is the largest, say h(C) > h(B) > h(A), then we increment the height-to-length function appropriately, and proceed to the triangle on the other side of AC. The other cases where h(C) is smallest or largest are similar.
  • if we entered through AB, and h(B) > h(C) > h(A), then we proceed clockwise through all other triangles incident to C. We check which ones have paths of height C outgoing, take any even-indexed path, and follow it.
  • If it ends up going back to C, we remove both the triangles through which the cycle touched C, and try again with an even-indexed path.
  • If it hits the boundary, we remember this fact, and continue processing even-indexed paths.
  • If we're left with only one path, and we haven't hit the boundary yet, then we mark the triangle CDE through which this path exits as a "stopper", and then branch into tree-searching BC and CA.
  • If we found at least one even-indexed path leading to the boundary, we now also check all the odd-indexed paths except the first and last one (because the first and last one will be checked by tree-searches through BC and CA). If any of them hit the west boundary, we take the current value of the function at C plus the length of the shortest path from C to the boundary as a candidate solution; and then proceed to branch into BC and CA.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +50
  • Проголосовать: не нравится