cel.in's blog

By cel.in, 3 months ago, In English

Hi everyone!

The fourth round of COCI will be held today, January 24th at 14:00 UTC. You can access the judging system here. If you are not familiar with the COCI contest format, we encourage you to read the announcement.

The round was prepared by nvujica, FranSkarica, coolplum and me.

Feel free to discuss the problems in the comment section after the contest ends.

Hope to see you today!

  • Vote: I like it
  • +44
  • Vote: I do not like it

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

is there an elegant solution for magija full points? also how to solve sladoled?

  • »
    »
    3 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    I got a full score for sladoled, but I suspect it was not the intended solution. Firstly, it's clear that each stand can be solved separately. Keep a boolean array of which flavours can be achieved, and as each scoop is delivered, do a sweep through the array to update it in the usual way. To get that from partial to a complete score, I optimised it using bit packing, updating 64 bits at a time. That is more complex when b < 64, so I

    1. added a special code-path for that case, which handles propagation within a single 64-bit word using binary lifting;
    2. added an early-out so that if a scoop is delivered which can already be made as a sum of other scoops, the array is not updated at all.

    The latter limits the number of times the more complex code-path is needed to O(64N).

  • »
    »
    3 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    For Magija

    My solution for $$$O(nlog^2(n))$$$ is to merge components just like in $$$O(nq)$$$ solution but here we want to merge elements that come from different components.

    Let's see how to check if merging $$$[a, a+x]$$$ and $$$[b, b+x]$$$ changes anything. Let's have an array $$$d$$$ where $$$d_i$$$ shows a representative of union where $$$i$$$ is. Here we want to check if the corresponding substrings of $$$d$$$ are same. To do that we compare their hashes.

    Now se can check what positions differ in substrings by binary searching them. To quickly get hashes of substrings of $$$d$$$ we use segment tree. When merging two components we need to update the array $$$d$$$. Iterate over elements in smaller component and change $$$d$$$ on those positions and update the segment tree. That's $$$O(n log(n))$$$ changes in total, with a time $$$O(log(n))$$$ complexity each. Obtaining a position that differs with binary search + segment tree is $$$O(log^2(n))$$$.

    So that is $$$O(n log^2(n))$$$ in total.

    • »
      »
      »
      3 months ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      my friend wrote this up and it passed only for 73. seems both TL and ML are very tight for this solution, so i was hoping for a maybe more elegant solution that would pass more comfortably?

    • »
      »
      »
      3 months ago, hide # ^ |
       
      Vote: I like it +27 Vote: I do not like it

      There is a solution only involving dsu.

      We have logn DSUs. If $$$i$$$ and $$$j$$$ are in the same component in the $$$k$$$-th dsu, it means that we can swap the intervals $$$[i, i+2^k-1]$$$ and $$$[j, j+2^k-1]$$$.

      So for each query of type 2, we can split the intervals in powers of 2 based on the length, and for each part do the following recursive process:

      Suppose we should unite the intervals starting at $$$i$$$ and $$$j$$$ of length $$$2^k$$$.

      If they are already merged, terminate.

      Otherwise, merge then and do the same to the left and right half of both.

      Notice that for each dsu, we have at most $$$N-1$$$ merge operations, and at each step of the process we make a valid merge, so the time complexity is $$$NlogN$$$

      Code: https://pastebin.com/XCUMjHmT

      Though I gotta say that it was hard to squeeze the memory limit and was not needed to be that tight!

      • »
        »
        »
        »
        3 months ago, hide # ^ |
         
        Vote: I like it +13 Vote: I do not like it

        Your solution was supposed to give only 73 points (and is the reason for the tight memory limit), but a lot of contestants managed to squeeze it. dinohaur's solution is the intended one.

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

I have a solution which passes sladoled in $$$\mathcal{O} \left(\frac{N W \log W}{64} \right)$$$:

int n, q;
cin >> n >> q;
for (int i = 1; i <= n; i++) bs[i][0] = 1;
while (q--) {
    int a, b;
    cin >> a >> b;
    if (!bs[a][b]) {
      for (; b <= 50000; b <<= 1) {
        if (bs[a][b]) break;
        bs[a] |= bs[a] << b;
      }
    }
    cout << bs[a].count() - 1 << '\n';
}
  • »
    »
    3 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    That's roughly what I wrote initially but it TL'ed. I suspect the difference may be the if (bs[a][b]) break; which I didn't have.

    • »
      »
      »
      3 months ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      Hi, I am the author of the task. The solution above using bitsets and breaking when possible is intended and the official solution for the task. Adding that break significantly boosts the solutions performance so we decided to include it.

      • »
        »
        »
        »
        3 months ago, hide # ^ |
         
        Vote: I like it +1 Vote: I do not like it

        Thanks. Out of interest, does the break improve the big-O complexity? I can believe it might, but couldn't see an obvious proof.

      • »
        »
        »
        »
        2 months ago, hide # ^ |
        Rev. 16  
        Vote: I like it 0 Vote: I do not like it

        a

        The time complexity goes up when $$$W$$$ and $$$n$$$ increases, but I have not found a reasonable formula. Maybe regression analysis would help?

        I suspect the TC is $$$O(QW(\log(W)-\log(Q/n)))$$$?

»
3 months ago, hide # |
 
Vote: I like it +2 Vote: I do not like it

What's the difference between these 2 codes on 3rd problem?

Why does this code get 56 pts
while this code gets 73 pts?

I think both of them should only get 45 pts.

»
3 months ago, hide # |
 
Vote: I like it +1 Vote: I do not like it

Salam! thanks for the contest.

Can you open upsolving?

how to solve last problem?