n0sk1ll's blog

By n0sk1ll, history, 15 hours ago, In English

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!

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

»
15 hours ago, # |
Rev. 2   Vote: I like it +27 Vote: I do not like it

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);