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

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

Today, I had spent hours trying to solve problem : (https://codeforces.net/contest/1334/problem/C) and submitted several solutions with an O(n) complexity, but I kept getting a TLE. After some further inspection, I changed from using cin to scanf, and my solution was finally accepted. While it's well-known that scanf is slightly faster than cin, I was surprised by how much of a difference it actually made in this case.

TLE Code : 284211972 Accepted Code : 284212724

This blog may not be overly educational, but I just want to highlight that even a O(n) solution can lead to a TLE error. Understanding this can help you avoid the frustration and wasted time that I experienced.

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

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

ios::sync_with_stdio(false);cin.tie(nullptr); cout.tie(nullptr);

Use this if you want to use cin/cout

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

    what does cout.tie(nullptr) do?

    explanation

    • »
      »
      »
      7 недель назад, # ^ |
        Проголосовать: нравится -28 Проголосовать: не нравится

      cout = Output + cout.flush(). But if you use cout.tie(nullptr) it will untie the cin with cout. So cout = Output only. In interective problems if you don't use cout.tie(nullptr); you don't have to use flush manually as it will be done automatically.

      Using this will help a lot with time complexity specially when you have multiple test cases.

      And forgive my poor English

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

      Nothing because by default cout is not tied to anything.

      • »
        »
        »
        »
        7 недель назад, # ^ |
          Проголосовать: нравится -19 Проголосовать: не нравится

        I think cout is tied with cin. Everytime you use cin after a cout it flushes the output. Though I am not sure if cout.tie(nullptr) or cin.tie(nullptr); does the work of untie.

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

          Actually, not. You can double check this, just print the result of std::cout.tie(nullptr) (the method returns the current tied stream and if there is no tied stream, a null pointer is returned).

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

            Yeah, Got it.So, I am just using a line for no reason.I just need cin.tie(nullptr);. Thanks.

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

I thought everyone learns to put cin.tie(0) -> sync_with_stdio(0) in their code the first day they start cp.

Guess not :/

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

    I know thats a fundamental thing in CP but I never thought that it would matters that much but I guess im wrong lol.

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

      Will highly recommend you to watch this vid Here You will be able to visualise how fast it is and why does it happen ?

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

it does not affect complexity, QED.

»
7 недель назад, # |
Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

std::cin is tied (or synchronized) with std::cout by default in C++, which means it will ensure that your stdout will always be flushed before the input operations. It makes your program slows due to the fact that you have to flush the output before you take the next input from stdin. If you provide those:

ios::sync_with_stdio(false);
cin.tie(0);

Then they are untied, and the output will only be flushed when stdout is full, or your program has been terminated. That's why you see the whole output after reading and processing all test cases. And that's why it is said that using endl is not a good practice as it flush your output immediately, which means using those two lines of codes above are useless. This blog is quite nice and you should take a look.

(I thought I have remind you before but you didn't really care about that).