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

Автор Mkswll, 16 месяцев назад, По-английски

I actually thought I had a quite good understanding of std::set and std::multiset until D of the last Div. 2 contest taught me a lesson (you can tell from my submissions on D). So I decided to write this blog to prevent other people from making similar mistakes when overloading the < operator in sets (if these are just common sense then it's probably just my skill issue). If there exists a blog that talks about similar things please do inform me.

Try to think of the output for each of the following codes.

1) (with std::set)

Code 1
Explanation 1

2) (with std::multiset)

Code 2
Explanation 2

3) (with std::multiset, very similar to (2))

Code 3
Explanation 3

These tips are really about the same core idea, but I decided to write three tips because I actually made all these three mistakes (which made my debugging life despairing). Hope these are helpful to you!

(PS: I love how the name of the problem is literally "More Wrong" xd)

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

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

From where I can learn this Operator Overloading ? Like in Sets and Multisets (because I couldn't understand this return (r — l < t.r — t.l)

  • »
    »
    16 месяцев назад, # ^ |
    Rev. 3   Проголосовать: нравится +5 Проголосовать: не нравится

    It basically means the rules when it comes to compare two structs. Here, the author defines node a is less than node b if a.r-a.l is less than b.r — b.l. Another approach would be using the "friend" key word:

    struct node{
        int l, r;
        friend bool operator < (const node &a, const node &b){
            return a.r - a.l< b.r - b.l;
        }
    };
    

    My understanding of the differences of whether or not using the "friend" keyword is third person or first person point of view. Without friend, you simply compare current node's attribute with another node-type variable and calling that variables attributes. USACO guide explained some sorting techniques, you can check it out. Cuz I don't think I have explained it very well

»
16 месяцев назад, # |
  Проголосовать: нравится -14 Проголосовать: не нравится

Yes. There exists a similar blog regarding this particular topic. Please, do read it!

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

I really wonder how the builtin std::set can think two elements are some just only from a < operator , I think it should be that you need to define a == operator too for sets to avoid confusions like this

  • »
    »
    16 месяцев назад, # ^ |
    Rev. 3   Проголосовать: нравится +11 Проголосовать: не нравится

    For any c++ STL class or function, the provided comparator must conform to a Strictly Weak Ordering, which you can read about here.

    TL;DR: (answer to your question)

    A Strictly Weak Ordering doesn't allow two elements $$$a$$$ and $$$b$$$, where $$$a$$$ is not less than $$$b$$$, $$$a$$$ is not greater than $$$b$$$ but also $$$a$$$ is not equal to $$$b$$$.

    A strictly weak ordering defines equality as follows: If $$$a$$$ is not less than $$$b$$$ and $$$a$$$ is not greater than $$$b$$$, then $$$a$$$ is equal to $$$b$$$. In code, the condition a == b is equivalent to the condition !(a < b) && !(b < a) for any Strictly Weak Ordering.