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

Автор Rukashi, история, 3 года назад, По-английски

Hi guys, so here's the thing:

I was so frustrated while submitting a solution to this problem : D. Reality Show, and constantly receiving a TLE verdict. I was pretty sure that the time complexity of my code was acceptable, so I decided to read the code from another. It turns out, my solution resembles their code, and after being confused for a while, I realized that they submitted it in C++ 20. After changing the language, my previous TLE code was accepted. I'm really confused right now; it's like there are some magic in C++ 20 or something.

Here is my submission:

225519286 (here's the C++ 17) 225519370 (here's the C++ 20)

Can anyone explain this to me? Thanks! :3

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

»
3 года назад, скрыть # |
 
Проголосовать: нравится -7 Проголосовать: не нравится

haha!?

»
3 года назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +5 Проголосовать: не нравится

As it says, C++20 is 64bit, but C++17 is 32bit.

Maybe this will make your code faster?

If you try using C++17(64bit) one, you can also AC.

  • »
    »
    3 года назад, скрыть # ^ |
     
    Проголосовать: нравится +22 Проголосовать: не нравится

    Ye, this has nothing to do with C++17 vs C++20. For example, submitting in C++17(64 bit) also results in AC 225529315.

    For the future, my advice is to always submit using C++20(64 bit). The 32 bit versions are a relic of the past that shouldn't be used.

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

      Interesting, but for some reason when I was testing out my BIT template, I always get RE with C++ 20 but the same code got accepted with C++ 17, can you check why this is happening? C++ 20: https://codeforces.me/contest/61/submission/223433081 C++ 17: https://codeforces.me/contest/61/submission/223433050

      • »
        »
        »
        »
        3 года назад, скрыть # ^ |
         
        Проголосовать: нравится +3 Проголосовать: не нравится

        Your suffix_vec vector has size n, but you try to access n-th element

      • »
        »
        »
        »
        3 года назад, скрыть # ^ |
        ← Rev. 2  
        Проголосовать: нравится 0 Проголосовать: не нравится

        In my personal experience, this is usually due to different operating system versions on the evaluation machines. In summary, Windows tend to be more lenient on such undefined behavior.

        Below are some of my personal findings. They may not be correct, but they might give you some hints.

        If you carefully read each item in the language column (especially the content in parentheses), you will notice that the 64-bit versions are all based on Windows (msys2 and winlibs). I typically use the following program for testing:

        #include <bits/stdc++.h>
        
        int main() {
            std::map<int, int> dic;
            long long x = dic.size() - 1;
            std::cout << x << "\n";
            return 0;
        }
        

        When compiled on a Windows system, you will get $$$-1$$$, which is exactly what we want. However, when compiled on Non-Windows (I can't be sure what system they are using, but it's highly likely to be Lumix), you will get a random number. You can try testing it on CodeForces Custom Test.

        image.png

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

          What might be a reason is that, size() returns a number of size_t type, which is unsigned. That means, if you minus one, you won't get a correct answer.

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

          That is not undefined behaviour.

          The type of .size() is size_t which is an unsigned 32 bit integer on 32 bit systems, and an unsigned 64 bit integer on 64 bit systems.

          The reason the output is 4294967295 on 32 bit systems is that

          unsigned int x = -1; // x becomes 4294967295 
          long long y = x; // y becomes 4294967295 
          

          The reason the output is -1 on 64 bit systems is that

          unsigned long long x = -1; // x becomes 18446744073709551615
          long long y = x; // y becomes -1
          

          A simple way to avoid this bug is to cast .size() to an int. That way the result will always be -1 on both 32 bit systems and 64 bit systems.

          #include <bits/stdc++.h>
          
          int main() {
              std::map<int, int> dic;
              long long x = (int) dic.size() - 1;
              std::cout << x << "\n";
              return 0;
          }
          
    • »
      »
      »
      3 года назад, скрыть # ^ |
      ← Rev. 3  
      Проголосовать: нравится +3 Проголосовать: не нравится

      There are some uses for 32-bit, especially if memory is the limiting factor. This code 223013153 gets RTE on C++20 (64) because of stack overflow, on other compilers it gets AC.

      I was curious about that and measured the size of stack frame on each compiler:

      G++20 (64) 288 B

      G++17 (64) 192 B

      G++17 112 B

      (by measured I mean I saved the address of some local variable to a global pointer, and printed the difference of this pointer with local variable of the recursive function call — no idea if this is guaranted to be correct, but it is consistent with the fact that only G++20 RTEs)

      This is just one submission, but even if G++20 (64) was as efficient as G++17 (64) this still leaves nearly 2x memory usage compared to 32-bit.

»
3 года назад, скрыть # |
 
Проголосовать: нравится +9 Проголосовать: не нравится

Try using GNU G++17 9.2.0 (64 bit, msys 2) instead of GNU G++17 7.3.0; 64-bit is almost always faster than 32-bit.

»
3 года назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Because long long is faster in 64 bit compilers.

»
3 года назад, скрыть # |
 
Проголосовать: нравится +7 Проголосовать: не нравится

we live we love we lie