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

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

Good evening, Codeforces community!

Let me introduce a useful pattern that appears in many algorithms and source codes.

Why you should pass collections by reference in C++

Take a look at this code:

Code

It is a DFS implementation. Graph $$$g$$$ is given that has $$$n$$$ nodes and $$$m$$$ edges. Can you guess the time complexity?

Time Complexity
But why?

Here is the correct code:

Code
What is different?

When you shouldn't pass by reference

Today, I attempted 2053D - Refined Product Optimality during the official contest. Briefly, given two arrays $$$a_1,a_2,\ldots ,a_n$$$ and $$$b_1,b_2,\ldots, b_n$$$ and $$$q$$$ queries, one should find a greedy algorithm to answer the queries.

My first greedy idea was to sort both arrays and then $$$\min(a_1,b_1) \cdot \min(a_2,b_2) \cdot \ldots \cdot \min(a_n,b_n)$$$ is the answer. Before moving onto the main $$$\mathcal{O}((n+q)\log n)$$$ solution, I wanted to test my idea with brute force in $$$\mathcal{O}(nq \log n)$$$ time. I used the following code:

Code

Since I had Wrong Answer on the sample (test $$$1$$$), I moved on to the next greedy idea. It was more complicated and difficult to implement. At least I had a proof that it was correct. Unfortunately, after spending two hours of implementing it during the contest, I failed. The second idea was just too difficult for handling the queries. The problem was impossible, or at least too hard for the position, I thought.

Fun fact: The first idea was correct. Its $$$\mathcal{O}((n+q)\log n)$$$ implementation that handles queries is simple as well. So, why did it give Wrong Answer?

Really, why?
What should I have done instead?

The problem is not impossible. I just made a blunder.

Final tips

  1. Passing local variables by reference is cool, but be careful when modifying them, as you might not like the result.

  2. Copying is useful when you don't want to keep changes.

  3. Reference is useful when you do want to keep changes globally and save some time and memory.

  4. Don't overcomplicate things.

  5. Learning from your own mistakes is good. Learning from somebody else's is better.

  6. Glory to Arstotzka!

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

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

Yeah, it happens. One of the worst kinds of bugs. I had plenty of similar bugs myself.

Here's a tip. If you want to pass by reference but don't want to accidentally change it, declare it with const in function. For example:

void coolfunction(const vector<int> &v);

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

Did the same mistake in this problem

tle code due to pass by value

it got accepted when passed with reference

I didn't knew it took (n+m) to copy vector of vector. Thanks for post.