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

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

The European Girls' Olympiad in Informatics 2023 took place from 15th to 21st of July in Lund, Sweden. The results can be found here: https://egoi23.se/scoreboard/. Huge congratulations prvocislo for winning the contest and all other contestants who did incredibly well.

The tasks where authored by snowysecret, Pajaraja, MladenP, bestial-42-centroids, nigus, 4fecta and dj3500.

The problem where prepared by the scientific committee consisting of Cupcakess, nigus, simonlindholm, Xylofo, zehnsechs, deadkey and dj3500.

We also thank our testers: Petr, Eliden, Cauchico, Gullesnuffs and VladGavrila.

An online mirror is available with flexible start time on Kattis running until July 24.

The problems can also be found individually on Open Kattis or on the EGOI23 website. You are welcome to discuss the problems in the comments!

The difficulty ranges between Div2 C and Div1 F, and we are very happy about the quality of the problems.

We are looking forward to seeing you at EGOI 2024 in Eindhoven, the Netherlands.

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

»
16 месяцев назад, # |
  Проголосовать: нравится +17 Проголосовать: не нравится

I just only wondering, why not CMS?

»
16 месяцев назад, # |
  Проголосовать: нравится +7 Проголосовать: не нравится

It's been a wonderful event and problems were great. Iceland looks forward to attending again for EGOI 2024.

»
16 месяцев назад, # |
  Проголосовать: нравится +14 Проголосовать: не нравится

Will the closing ceremony be live streamed?

»
16 месяцев назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

It was a wonderful EGOI! Thanks for your hard work on this event. See you next year.

»
16 месяцев назад, # |
Rev. 2   Проголосовать: нравится +22 Проголосовать: не нравится

Does anyone know the solution to day 2 problem 4, guessing game?

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +52 Проголосовать: не нравится

    My solution, which had K = 5, had Anna give information to Bertil in phases, where the first n₁ houses she is led to constitute the first phase, the next n₂ houses constitute the second phase, and so on. In each phase, Anna should give all the information that Bertil needs in order to determine exactly which houses she visited in the previous phase. This is important because when Anna knows which houses were in the previous phase, she can discard them as they are no longer relevant. Finally, when Anna only has a small number of houses left to visit, I used a precomputed bruteforced strategy which allowed Anna to tell Bertil both which houses were part of the previous phase and which two houses Bertil should use as guesses.

    In the first phase, Anna just writes 1 on all the doors she visits. This gives Bertil a great deal of information about which doors were in the first phase, but he can't know for sure if a door with a 1 on it was part of the first phase or if it was part of a later phase and just happened to get a 1 anyway. But I designed the strategy so that the vast majority of all 1s would be in the first phase (for example by avoiding writing any 1s in the second phase), which means that only a relatively small amount of information is needed to identify which 1s belonged to the first phase. To send this information to Bertil, Anna uses an error-correcting code and writes numbers in the second phase in accordance with that code. The reason why the code has to be error-correcting is that Anna can't control which houses are in the second phase and which ones are in the third or later phase (these are the errors).

    Designing the code is the hardest part of this solution. My solution was to encode whether each house was part of the first phase as either 0 or 1, and then hash each prefix of the resulting binary vector, and reduce the hash modulo K. Then Bertil could use Viterbi decoding to reconstruct the vector in a streaming manner.

    I'm leaving out quite a bit of details here, and I'm happy to admit that I would definitely not have been able to implement this solution during the competition. I was one of the testers for the competition, and making this solution work took me days! I'm impressed that prvocislo managed to get a K = 17 solution working during the contest!

    • »
      »
      »
      16 месяцев назад, # ^ |
        Проголосовать: нравится +32 Проголосовать: не нравится

      Gullesnuffs Mind elaborating on what's done during encoding phase 2? I don't quite get the explanation; there are $$$\binom{100000}{n_1}$$$ potential binary strings after phase 1 — how do you encode this using only $$$n_2$$$ numbers?

      Also, I'm curious what's the best $$$K$$$ you can obtain as a function of $$$N$$$.

      • »
        »
        »
        »
        16 месяцев назад, # ^ |
          Проголосовать: нравится +11 Проголосовать: не нравится

        That's a good question, that's one of the things I glossed over. What allows me to encode all this information is that I avoid using any 1s during the second phase, which means that Bertil only has to get enough information to identify the houses in the first phase out of $$$100000-n_2$$$ houses, and because in my solution I have $$$n_1 \gg n_2 \gg n_3 \gg ...$$$ it holds that the entropy is just $$$\log \binom{100000-n_2}{n_1} \approx n_3 \log \frac{100000}{n_3}$$$, which is smaller than $$$n_2$$$.

        After I've used the phase 2 houses to encode which houses were in phase 1, I use the phase 3 houses to encode which houses were in phase 2, and none of the houses in phase 3 are allowed to have the same number as they would have had had they been in phase 2, which is analogous to how phase 2 houses are not allowed to have the number 1.

        In my solution $$$K$$$ is not dependent on $$$N$$$, it has $$$K=5$$$ for any $$$N$$$. I strongly suspect that $$$K=4$$$ is also possible for any $$$N$$$ (and perhaps even $$$K=3$$$) but it may be computationally infeasible, at least with my approach.

        • »
          »
          »
          »
          »
          15 месяцев назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Is a full solution description available somewhere? I don't see how you would encode the positions of the houses in the >= 3rd phase using the numbers in the 2nd phase, since you don't know which houses will be in the >= 3rd phase when determining the numbers in the second phase.

          • »
            »
            »
            »
            »
            »
            15 месяцев назад, # ^ |
              Проголосовать: нравится +10 Проголосовать: не нравится

            I don't encode the houses in phase 3 using the houses in phase 2, but the other way around: I encode the houses in phase 2 using the houses in phase 3.

            I haven't written up any more detailed descriptions of the solution, but my implementation is available here: https://github.com/Gullesnuffs/guessing-game (Warning: it's complicated, and weighs in at 1100 LOC)

            • »
              »
              »
              »
              »
              »
              »
              15 месяцев назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              Given that it uses hashing, how can you be sure that it works on all inputs?

              • »
                »
                »
                »
                »
                »
                »
                »
                15 месяцев назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится

                It doesn't, it works in approximately 99.98% of all cases (which can be improved with more pre-computation or at the expense of slower decoding).

                It can be proven that there exists a hash function that would make the solution pass 100% of the time, but finding that function by brute force is infeasible. However, the solution only really fails during phases with relatively small $$$n$$$, and the error probability decreases when $$$n$$$ grows. The error probability decreases sufficiently rapidly that it should be possible to pick a uniformly random hash function and then with non-zero probability this hash function will make the solution succeed for all inputs. I haven't written a formal proof of this, though, so it should be taken with a grain of salt. And also, it would be impossible to verify that any given random hash function always succeeds, so in order to achieve that you would have to use a deterministic code. It might be possible to get Reed-Solomon to do the job, but I'm not sure.

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +67 Проголосовать: не нравится

    Hi! I'm the author of this task. Here's the solution writeup that I created when submitting the problem to the EGOI. As you might notice, I originally submitted the task intending $$$K = 17$$$ to be the full solution. There is actually a pretty clean implementation for this (looks kind of like the update and query functions of a simple segment tree):

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MN = 100005;
    
    int n, st[MN * 4], a[MN];
    
    int upd(int l, int r, int v, int dep, int x, int idx) {
        if (++st[idx] == r - l + 1 && !v) v = dep;
        if (l == r) return v;
        int mid = (l + r) / 2;
        if (x <= mid) return upd(l, mid, v, dep + 1, x, idx * 2);
        else return upd(mid + 1, r, v, dep + 1, x, idx * 2 + 1);
    }
    
    pair<int, int> solve(int l, int r, int dep) {
        if (l + 1 >= r) return {l - 1, r - 1};
        int mid = (l + r) / 2;
        int lc = 0, rc = 0;
        for (int i = l; i <= mid; i++) if (a[i] == dep) lc = i;
        for (int i = mid + 1; i <= r; i++) if (a[i] == dep) rc = i;
        if (lc && rc) return {lc - 1, rc - 1};
        else if (lc) return solve(mid + 1, r, dep + 1);
        else return solve(l, mid, dep + 1);
    }
    
    int init(int N) {
        n = N;
        int K = 1, len = 2;
        while (len < N) len *= 2, K++;
        return K;
    }
    
    int choose_value(int i) {
        return upd(1, n, 0, 0, i + 1, 1);
    }
    
    pair<int, int> guess_secret(vector<int> A) {
        n = A.size();
        for (int i = 0; i < n; i++) a[i + 1] = A[i];
        return solve(1, n, 1);
    }
    
    int main() {
        cin.tie(0), cin.sync_with_stdio(0);
        cout.tie(0);
        int P, N;
        cin >> P >> N;
        if (P == 1) {
            int K = init(N);
            cout << K << endl;
            for (int i = 0, u; i < N - 1; i++) {
                cin >> u;
                cout << choose_value(u) << endl;
            }
        } else {
            vector<int> A(N);
            for (int i = 0; i < N; i++) cin >> A[i];
            pair<int, int> guess = guess_secret(A);
            cout << guess.first << " " << guess.second << endl;
        }
    }
    

    However, around two weeks before the contest, I was told that someone from the scientific committee had found a more efficient solution with $$$K \le 7$$$. This was very surprising news for me, as I struggled for a long time to see how to whittle $$$K$$$ down even further. I believe it is possible to directly optimize my solution slightly by adjusting the branching factor of some of the layers of segments, but I don't see any clean techniques that get it all the way down below $$$7$$$. I'm also curious to see if anyone has a nice implementation of the full solution!

    • »
      »
      »
      16 месяцев назад, # ^ |
        Проголосовать: нравится +58 Проголосовать: не нравится

      Here's a solution for $$$512\le N\le 9!$$$ with $$$K=10$$$ that doesn't take too long to implement. For $$$N=100000$$$, this can be improved to $$$K=9$$$ with some more effort.

      Encoding: Write ones for the first $$$N-2^9$$$ houses. Then compute the sum of the remaining house labels modulo $$$N$$$, and encode this sum as a permutation $$$p_1\dots p_9$$$ of $$$2\dots 10$$$. For the remaining houses, write $$$2^8$$$ occurrences of $$$p_1$$$, $$$2^7$$$ occurrences of $$$p_2$$$, ..., $$$2^0$$$ occurences of $$$p_9$$$ following 4fecta's solution above for $$$N=512$$$, but writing $$$p_{dep}$$$ instead of $$$dep$$$.

      Decoding: First, we identify $$$p$$$. If the number written on the last house is $$$1$$$, then we decode $$$p$$$ into the sum and subtract out the labels of all houses with numbers greater than $$$1$$$; the remainder will now equal the last house. Otherwise, we can identify the house using the decoding scheme from 4fecta's solution above.

»
16 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

If I am not mistaken, if the window ends then you can not submit (upsolve). Can someone fix that?

»
16 месяцев назад, # |
  Проголосовать: нравится +19 Проголосовать: не нравится

Will the problems come to codeforces gym?

»
16 месяцев назад, # |
  Проголосовать: нравится +71 Проголосовать: не нравится

I realize it's not easy to come up with novel and interesting task, but I feel like Problem 2 Day 2 task is too "textbook" for the standard of an international OI.

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +53 Проголосовать: не нравится

    yeah I agree it is quite standard. I think it is a decent problem, and it fit into the rest of the problemset in terms of topics and difficulty.

    But I appreciate that you have high expectations, it is something for the scientific committee to think about for next year.

»
16 месяцев назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

When will solutions be uploaded?

»
16 месяцев назад, # |
Rev. 4   Проголосовать: нравится +2 Проголосовать: не нравится

.

»
16 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Does anyone know the solution to day 1 problem 1 , inflation?

  • »
    »
    16 месяцев назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    First, let's solve the problem if we didn't have the INFLATION operation. It's easy to see that we can keep a data structure (for example a map) with the number of occurences of each value ($$$f_x$$$ = how many dishes have price x). Now, we can easily to the updates:

    $$$answer = answer - x \cdot f_x$$$ // we need to subtract what we had before

    $$$answer = answer + y \cdot f_x$$$ // we add the new stuff

    $$$f_y = f_y + f_x$$$ // every dish which had price x will now have price y

    $$$f_x = 0$$$ // there are no longer any dishes with price x

    After each query, the answer is held in $$$answer$$$(which is initially the sum off all prices).

    To fully solve the problem, we can observe that the "brute force" is to do replace $$$f_i$$$ with $$$f_{i-x}$$$ after each INFLATION operation. This would take too much time, so instead we can see that when we make a SET operation, we can actually just replace the values $$$x$$$ and $$$y$$$ with $$$x - inflated$$$, $$$y - inflated$$$, where $$$inflated$$$ = the sum of values $$$x$$$ from the INFLATION updates we made before this SET operation. It shouldn't be too hard to see why this works.

    Time complexity: $$$O((n + q) log_2 n )$$$

    • »
      »
      »
      16 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Very grateful my friend! Nice informations presented here.

    • »
      »
      »
      16 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Great, for SET operations, remember to handle the case $$$x=y$$$ separately (you should do nothing).

»
16 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Hi, may I ask for the solution for DAY 2 C: Sopsug. Thanks

»
16 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Will an editorial be published after the mirror ends ?

»
16 месяцев назад, # |
  Проголосовать: нравится +20 Проголосовать: не нравится

The problems have been added to the Eolymp.

The virtual participation is possible.

  • »
    »
    15 месяцев назад, # ^ |
    Rev. 3   Проголосовать: нравится +16 Проголосовать: не нравится

    When i submit this code in d2C, it takes 100 points.

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    
    	cout << "NO";
    }
    
»
16 месяцев назад, # |
Rev. 2   Проголосовать: нравится +3 Проголосовать: не нравится

why in d1 we can add all the edges ai,j <= bi,j and if there was a solution then nothing will break?

»
16 месяцев назад, # |
  Проголосовать: нравится +15 Проголосовать: не нравится

is there a correct solution for Day 2 problem C? As I see a lot of wrong submissions passed for 100 points, including mine.

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +23 Проголосовать: не нравится

    yes, the test data for day2C is quite weak unfortunately. Here is a solution sketch I wrote just now:

    Spoiler
»
15 месяцев назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

How to solve D1P2?