MIT Puzzle: The Best Time to Party
Good to see you're not doing a using namespace std ;).
Of course it doesn't really hurt in a source file (.cpp) (it does in a header file!),
but even then that is still considered bad practice. My personal reason to just always type the namespace is because it makes code easier to read (you know what is part of a namespace and which and don't have to guess that) and it is easier to search with regular expressions and the like.

While the standard does not use class names that begin with an upper case letter, many good coders do. It allows you - in fact - to have your own classes to stand out better, and using both upper case and lower case adds more state to your namespace (aka, less collisions). For example, you can call your class Range and a Range variable range.

Also for both, readability and regular expression searches, I strongly recommend only to use complete English words for any class, variable or function name and never resort to abbreviations. The only exceptions to this rule are local variables that are so local (used in a scope of only a few lines) that you can easily see their declaration and use on one screen and where their meaning is mostly irrelevant(!). For example a counter of a for loop can be called i if you must.

Also for ease of regular expression search and understandability (maintenance) of code it is a good idea to use the same name for variables that contain the same object (you copied a value from one to the other). Ok, that is normally not possible unless you pass them as function argument (you can't write range = range) but you'll surprised how often it is; for example use range_end for every variable that means "the end of a range". Why am I mentioning this? Well, this is the reason that class member variables often have a prefix (either M_ or m_ or something. I use m_. That way you avoid collisions with local variables with the same name, and member functions with the same name.

C++ provides classes with a reason: to write Object Oriented code. Encapsulation is part of that. In almost all cases your class member variables should be private!

For (ostream based) debugging output, it is a good idea to make every class
writable to an ostream.

std::move is just a cast, from an lvalue reference to an rvalue reference, and only useful when you pass the result to a function that takes an rvalue reference (aka, you pick the right overloaded function with it). Where you used std::move the argument isn't an lvalue reference, nor do you pass the result of the std::move to a function that accepts an rvalue reference, so using std::move there is nonsense. PS By convention a moved object (whose rvalue reference was passed to a function) should only be destructed afterwards (in all but exceptional cases). So if you cast an lvalue reference to an rvalue reference then that variable had better be passed in as an rvalue reference in the first place. The typical use case therefore looks as follows:

void bar(Bar&amp;&amp; bar);

void foo(Bar&amp;&amp; bar)
{
  // Here bar is an lvalue reference!
  bar(std::move(bar));
  // Now 'bar' may no longer used, only destructed (by convention:
  // it is like that because one would expect that bar() makes it so.
}


This would work fine when foo() took an lvalue reference (foo(Bar&amp; bar)) but 
then the caller of foo wouldn't be aware of the fact that bar was moved and could "accidently" use bar still after returning from foo(bar).

Combining what we learned so far, I arrive at the follow code for Range:

class Range
{
  private:
    int m_start_time = 0;
    int m_end_time = 0;

  public:
    Range() = default;
    Range(int start_time, int end_time) :
        m_start_time(start_time),
        m_end_time(end_time)
        { }

    int start_time() const { return m_start_time; }
    int end_time() const { return m_end_time; }

    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, Range const&amp; range);
};


Well, that's enough for today.
I'll finish with my own stab at celeb_density:

int celeb_density(std::vector&lt;Range&gt; const&amp; schedule)
{
    // Do not pass an empty schedule.
    assert(!schedule.empty());          // #include &lt;cassert&gt;

    std::array&lt;unsigned int, 24&gt; hours; // #include &lt;array&gt;
    hours.fill(0);

    int best_time = schedule[0].start_time();
    int max_celebs = 1;
    for (auto range : schedule)
      for (int hour = range.start_time(); hour &lt; range.end_time(); ++hour)
        if (++hours[hour] &gt; max_celebs)
        {
          ++max_celebs;
          best_time = hour;
        }

    return best_time;
}