• stl_algo.h


    stl_algo.h
    // Filename:    <stl_algo.h>
    
    // Comment By:  凝霜
    // E-mail:      mdl2009@vip.qq.com
    // Blog:        http://blog.csdn.net/mdl13412
    
    // 这个文件中定义了一些STL关键的算法, 我仅仅给出一个思路,
    // 不进行详尽讲解, 具体算法请参考算法书籍, 推荐《算法导论》
    // 另外, 对于基础薄弱的, 推荐《大话数据结构》, 此书我读了一下
    // 试读章节, 适合初学者学习
    
    /*
     *
     * Copyright (c) 1994
     * Hewlett-Packard Company
     *
     * Permission to use, copy, modify, distribute and sell this software
     * and its documentation for any purpose is hereby granted without fee,
     * provided that the above copyright notice appear in all copies and
     * that both that copyright notice and this permission notice appear
     * in supporting documentation.  Hewlett-Packard Company makes no
     * representations about the suitability of this software for any
     * purpose.  It is provided "as is" without express or implied warranty.
     *
     *
     * Copyright (c) 1996
     * Silicon Graphics Computer Systems, Inc.
     *
     * Permission to use, copy, modify, distribute and sell this software
     * and its documentation for any purpose is hereby granted without fee,
     * provided that the above copyright notice appear in all copies and
     * that both that copyright notice and this permission notice appear
     * in supporting documentation.  Silicon Graphics makes no
     * representations about the suitability of this software for any
     * purpose.  It is provided "as is" without express or implied warranty.
     */
    
    /* NOTE: This is an internal header file, included by other STL headers.
     *   You should not attempt to use it directly.
     */
    
    #ifndef __SGI_STL_INTERNAL_ALGO_H
    #define __SGI_STL_INTERNAL_ALGO_H
    
    #include <stl_heap.h>
    
    __STL_BEGIN_NAMESPACE
    
    #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
    #pragma set woff 1209
    #endif
    
    // 选取a, b, c三个数中间的那个
    template <class T>
    inline const T& __median(const T& a, const T& b, const T& c) {
      if (a < b)
        if (b < c)
          return b;
        else if (a < c)
          return c;
        else
          return a;
      else if (a < c)
        return a;
      else if (b < c)
        return c;
      else
        return b;
    }
    
    template <class T, class Compare>
    inline const T& __median(const T& a, const T& b, const T& c, Compare comp) {
      if (comp(a, b))
        if (comp(b, c))
          return b;
        else if (comp(a, c))
          return c;
        else
          return a;
      else if (comp(a, c))
        return a;
      else if (comp(b, c))
        return c;
      else
        return b;
    }
    
    // 对于[first, last)区间内的元素调用判别式
    // 个人非常喜欢这个函数, 在C#中这个是语言层面就支持的
    template <class InputIterator, class Function>
    Function for_each(InputIterator first, InputIterator last, Function f) {
      for ( ; first != last; ++first)
        f(*first);
      return f;
    }
    
    // 查找指定区间内第一个值为value的元素
    template <class InputIterator, class T>
    InputIterator find(InputIterator first, InputIterator last, const T& value)
    {
      while (first != last && *first != value) ++first;
      return first;
    }
    
    // 查找指定区间内第一个满足判别式额元素
    template <class InputIterator, class Predicate>
    InputIterator find_if(InputIterator first, InputIterator last,
                          Predicate pred)
    {
      while (first != last && !pred(*first)) ++first;
      return first;
    }
    
    // 找出第一组满足条件的相邻元素
    template <class ForwardIterator>
    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last)
    {
      if (first == last) return last;
      ForwardIterator next = first;
      while(++next != last) {
        // 判断是否满足条件, 满足就返回
        if (*first == *next) return first;
        first = next;
      }
      return last;
    }
    
    // 使用用户指定的二元比较判别式, 其余同上面
    template <class ForwardIterator, class BinaryPredicate>
    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
                                  BinaryPredicate binary_pred)
    {
      if (first == last) return last;
      ForwardIterator next = first;
      while(++next != last) {
        if (binary_pred(*first, *next)) return first;
        first = next;
      }
      return last;
    }
    
    // 统计指定元素在指定区间内出现的次数
    template <class InputIterator, class T, class Size>
    void count(InputIterator first, InputIterator last, const T& value,
               Size& n)
    {
      // 统计操作要历遍整个区间
      for ( ; first != last; ++first)
        if (*first == value)
          ++n;
    }
    
    // 统计满足指定判别式的元素的个数
    template <class InputIterator, class Predicate, class Size>
    void count_if(InputIterator first, InputIterator last, Predicate pred,
                  Size& n) {
      for ( ; first != last; ++first)
        if (pred(*first))
          ++n;
    }
    
    #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
    
    template <class InputIterator, class T>
    typename iterator_traits<InputIterator>::difference_type
    count(InputIterator first, InputIterator last, const T& value)
    {
      typename iterator_traits<InputIterator>::difference_type n = 0;
      for ( ; first != last; ++first)
        if (*first == value)
          ++n;
      return n;
    }
    
    template <class InputIterator, class Predicate>
    typename iterator_traits<InputIterator>::difference_type
    count_if(InputIterator first, InputIterator last, Predicate pred) {
      typename iterator_traits<InputIterator>::difference_type n = 0;
      for ( ; first != last; ++first)
        if (pred(*first))
          ++n;
      return n;
    }
    
    #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
    
    template <class ForwardIterator1, class ForwardIterator2, class Distance1,
              class Distance2>
    ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2, ForwardIterator2 last2,
                              Distance1*, Distance2*) {
      Distance1 d1 = 0;
      distance(first1, last1, d1);
      Distance2 d2 = 0;
      distance(first2, last2, d2);
    
      if (d1 < d2) return last1;
    
      ForwardIterator1 current1 = first1;
      ForwardIterator2 current2 = first2;
    
      while (current2 != last2)
        if (*current1 == *current2) {
          ++current1;
          ++current2;
        }
        else {
          if (d1 == d2)
            return last1;
          else {
            current1 = ++first1;
            current2 = first2;
            --d1;
          }
        }
      return first1;
    }
    
    // 在[first1, last1)区间内, 查找[first2, last2)区间
    // 为了效率, 进行函数派发
    template <class ForwardIterator1, class ForwardIterator2>
    inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
                                   ForwardIterator2 first2, ForwardIterator2 last2)
    {
      return __search(first1, last1, first2, last2, distance_type(first1),
                      distance_type(first2));
    }
    
    template <class ForwardIterator1, class ForwardIterator2,
              class BinaryPredicate, class Distance1, class Distance2>
    ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2, ForwardIterator2 last2,
                              BinaryPredicate binary_pred, Distance1*, Distance2*) {
      Distance1 d1 = 0;
      distance(first1, last1, d1);
      Distance2 d2 = 0;
      distance(first2, last2, d2);
    
      if (d1 < d2) return last1;
    
      ForwardIterator1 current1 = first1;
      ForwardIterator2 current2 = first2;
    
      while (current2 != last2)
        if (binary_pred(*current1, *current2)) {
          ++current1;
          ++current2;
        }
        else {
          if (d1 == d2)
            return last1;
          else {
            current1 = ++first1;
            current2 = first2;
            --d1;
          }
        }
      return first1;
    }
    
    template <class ForwardIterator1, class ForwardIterator2,
              class BinaryPredicate>
    inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
                                   ForwardIterator2 first2, ForwardIterator2 last2,
                                   BinaryPredicate binary_pred) {
      return __search(first1, last1, first2, last2, binary_pred,
                      distance_type(first1), distance_type(first2));
    }
    
    // 在[first, last)内查找第一个满足连续count个value的位置
    template <class ForwardIterator, class Integer, class T>
    ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                             Integer count, const T& value)
    {
      if (count <= 0)
        return first;
      else {
        first = find(first, last, value);
        while (first != last) {
          Integer n = count - 1;
          ForwardIterator i = first;
          ++i;
          while (i != last && n != 0 && *i == value) {
            ++i;
            --n;
          }
          if (n == 0)
            return first;
          else
            first = find(i, last, value);
        }
        return last;
      }
    }
    
    // 好吧, 二元判别式自己指定的
    template <class ForwardIterator, class Integer, class T, class BinaryPredicate>
    ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                             Integer count, const T& value,
                             BinaryPredicate binary_pred) {
      if (count <= 0)
        return first;
      else {
        while (first != last) {
          if (binary_pred(*first, value)) break;
          ++first;
        }
        while (first != last) {
          Integer n = count - 1;
          ForwardIterator i = first;
          ++i;
          while (i != last && n != 0 && binary_pred(*i, value)) {
            ++i;
            --n;
          }
          if (n == 0)
            return first;
          else {
            while (i != last) {
              if (binary_pred(*i, value)) break;
              ++i;
            }
            first = i;
          }
        }
        return last;
      }
    }
    
    // 交换两个区间内的元素, 要求长度相同
    template <class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
                                 ForwardIterator2 first2)
    {
      for ( ; first1 != last1; ++first1, ++first2)
        iter_swap(first1, first2);
      return first2;
    }
    
    // 将[first, last)经判别式转换到result处
    template <class InputIterator, class OutputIterator, class UnaryOperation>
    OutputIterator transform(InputIterator first, InputIterator last,
                             OutputIterator result, UnaryOperation op)
    {
      for ( ; first != last; ++first, ++result)
        *result = op(*first);
      return result;
    }
    
    // 这个多了一个区间
    template <class InputIterator1, class InputIterator2, class OutputIterator,
              class BinaryOperation>
    OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, OutputIterator result,
                             BinaryOperation binary_op)
    {
      for ( ; first1 != last1; ++first1, ++first2, ++result)
        *result = binary_op(*first1, *first2);
      return result;
    }
    
    // 将[first, last)内的old_value都以new_value替代
    template <class ForwardIterator, class T>
    void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
                 const T& new_value)
    {
      for ( ; first != last; ++first)
        if (*first == old_value) *first = new_value;
    }
    
    // 将[first, last)内的满足判别式的元素都以new_value代替
    template <class ForwardIterator, class Predicate, class T>
    void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred,
                    const T& new_value)
    {
      for ( ; first != last; ++first)
        if (pred(*first)) *first = new_value;
    }
    
    // 与replace唯一不同的是会将元素复制到新的位置
    template <class InputIterator, class OutputIterator, class T>
    OutputIterator replace_copy(InputIterator first, InputIterator last,
                                OutputIterator result, const T& old_value,
                                const T& new_value)
    {
      for ( ; first != last; ++first, ++result)
        *result = *first == old_value ? new_value : *first;
      return result;
    }
    
    // 同上
    template <class Iterator, class OutputIterator, class Predicate, class T>
    OutputIterator replace_copy_if(Iterator first, Iterator last,
                                   OutputIterator result, Predicate pred,
                                   const T& new_value)
    {
      for ( ; first != last; ++first, ++result)
        *result = pred(*first) ? new_value : *first;
      return result;
    }
    
    // 将仿函数的处理结果填充在[first, last)区间内
    // 对于用户自定义类型要提供operator =()
    template <class ForwardIterator, class Generator>
    void generate(ForwardIterator first, ForwardIterator last, Generator gen)
    {
      for ( ; first != last; ++first)
        *first = gen();
    }
    
    // 和generate()差不多, 只是给定的是起点和个数
    template <class OutputIterator, class Size, class Generator>
    OutputIterator generate_n(OutputIterator first, Size n, Generator gen)
     {
      for ( ; n > 0; --n, ++first)
        *first = gen();
      return first;
    }
    
    // 将[first, last)中除了value的元素拷贝到result处
    // 注意: 这里使用的是operator =(), 用户自定义类型要注意资源的析构
    template <class InputIterator, class OutputIterator, class T>
    OutputIterator remove_copy(InputIterator first, InputIterator last,
                               OutputIterator result, const T& value)
    {
      for ( ; first != last; ++first)
        if (*first != value) {
          *result = *first;
          ++result;
        }
      return result;
    }
    
    // 将[first, last)中除了满足判别式的元素拷贝到result处
    // 注意: 这里使用的是operator =(), 用户自定义类型要注意资源的析构
    template <class InputIterator, class OutputIterator, class Predicate>
    OutputIterator remove_copy_if(InputIterator first, InputIterator last,
                                  OutputIterator result, Predicate pred)
    {
      for ( ; first != last; ++first)
        if (!pred(*first)) {
          *result = *first;
          ++result;
        }
      return result;
    }
    
    // 移除指定值的元素, 但是并不删除
    template <class ForwardIterator, class T>
    ForwardIterator remove(ForwardIterator first, ForwardIterator last,
                           const T& value)
    {
      first = find(first, last, value);
      ForwardIterator next = first;
      return first == last ? first : remove_copy(++next, last, first, value);
    }
    
    // 移除满足判别式的元素, 但是并不删除
    template <class ForwardIterator, class Predicate>
    ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
                              Predicate pred)
    {
      first = find_if(first, last, pred);
      ForwardIterator next = first;
      return first == last ? first : remove_copy_if(++next, last, first, pred);
    }
    
    template <class InputIterator, class ForwardIterator>
    ForwardIterator __unique_copy(InputIterator first, InputIterator last,
                                  ForwardIterator result, forward_iterator_tag) {
      *result = *first;
      while (++first != last)
        if (*result != *first) *++result = *first;
      return ++result;
    }
    
    
    template <class InputIterator, class OutputIterator, class T>
    OutputIterator __unique_copy(InputIterator first, InputIterator last,
                                 OutputIterator result, T*) {
      T value = *first;
      *result = value;
      while (++first != last)
        if (value != *first) {
          value = *first;
          *++result = value;
        }
      return ++result;
    }
    
    template <class InputIterator, class OutputIterator>
    inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
                                        OutputIterator result,
                                        output_iterator_tag) {
      return __unique_copy(first, last, result, value_type(first));
    }
    
    template <class InputIterator, class OutputIterator>
    inline OutputIterator unique_copy(InputIterator first, InputIterator last,
                                      OutputIterator result) {
      if (first == last) return result;
      return __unique_copy(first, last, result, iterator_category(result));
    }
    template <class InputIterator, class ForwardIterator, class BinaryPredicate>
    ForwardIterator __unique_copy(InputIterator first, InputIterator last,
                                  ForwardIterator result,
                                  BinaryPredicate binary_pred,
                                  forward_iterator_tag) {
      *result = *first;
      while (++first != last)
        if (!binary_pred(*result, *first)) *++result = *first;
      return ++result;
    }
    
    template <class InputIterator, class OutputIterator, class BinaryPredicate,
              class T>
    OutputIterator __unique_copy(InputIterator first, InputIterator last,
                                 OutputIterator result,
                                 BinaryPredicate binary_pred, T*) {
      T value = *first;
      *result = value;
      while (++first != last)
        if (!binary_pred(value, *first)) {
          value = *first;
          *++result = value;
        }
      return ++result;
    }
    
    template <class InputIterator, class OutputIterator, class BinaryPredicate>
    inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
                                        OutputIterator result,
                                        BinaryPredicate binary_pred,
                                        output_iterator_tag) {
      return __unique_copy(first, last, result, binary_pred, value_type(first));
    }
    
    template <class InputIterator, class OutputIterator, class BinaryPredicate>
    inline OutputIterator unique_copy(InputIterator first, InputIterator last,
                                      OutputIterator result,
                                      BinaryPredicate binary_pred) {
      if (first == last) return result;
      return __unique_copy(first, last, result, binary_pred,
                           iterator_category(result));
    }
    
    // 删除所有相邻重复元素
    template <class ForwardIterator>
    ForwardIterator unique(ForwardIterator first, ForwardIterator last)
    {
      first = adjacent_find(first, last);
      return unique_copy(first, last, first);
    }
    
    // 好吧, 删除所有相邻重复元素, 并拷贝到指定位置
    template <class ForwardIterator, class BinaryPredicate>
    ForwardIterator unique(ForwardIterator first, ForwardIterator last,
                           BinaryPredicate binary_pred)
    {
      first = adjacent_find(first, last, binary_pred);
      return unique_copy(first, last, first, binary_pred);
    }
    
    template <class BidirectionalIterator>
    void __reverse(BidirectionalIterator first, BidirectionalIterator last,
                   bidirectional_iterator_tag)
    {
      while (true)
        if (first == last || first == --last)
          return;
        else
          iter_swap(first++, last);
    }
    
    template <class RandomAccessIterator>
    void __reverse(RandomAccessIterator first, RandomAccessIterator last,
                   random_access_iterator_tag)
    {
      while (first < last) iter_swap(first++, --last);
    }
    
    // 将[first, last)内的元素倒置
    // 还是为了效率进行函数派发, 不做解释了
    template <class BidirectionalIterator>
    inline void reverse(BidirectionalIterator first, BidirectionalIterator last)
    {
      __reverse(first, last, iterator_category(first));
    }
    
    // 好吧, 和reverse的区别是会把处理后的元素拷贝到新区间
    template <class BidirectionalIterator, class OutputIterator>
    OutputIterator reverse_copy(BidirectionalIterator first,
                                BidirectionalIterator last,
                                OutputIterator result)
    {
      while (first != last) {
        --last;
        *result = *last;
        ++result;
      }
      return result;
    }
    
    template <class ForwardIterator, class Distance>
    void __rotate(ForwardIterator first, ForwardIterator middle,
                  ForwardIterator last, Distance*, forward_iterator_tag) {
      for (ForwardIterator i = middle; ;) {
        iter_swap(first, i);
        ++first;
        ++i;
        if (first == middle) {
          if (i == last) return;
          middle = i;
        }
        else if (i == last)
          i = middle;
      }
    }
    
    template <class BidirectionalIterator, class Distance>
    void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
                  BidirectionalIterator last, Distance*,
                  bidirectional_iterator_tag) {
      reverse(first, middle);
      reverse(middle, last);
      reverse(first, last);
    }
    
    // 这个你要是都不知道那就马上去学习数据结构的知识吧
    template <class EuclideanRingElement>
    EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
    {
      while (n != 0) {
        EuclideanRingElement t = m % n;
        m = n;
        n = t;
      }
      return m;
    }
    
    template <class RandomAccessIterator, class Distance, class T>
    void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
                        RandomAccessIterator initial, Distance shift, T*) {
      T value = *initial;
      RandomAccessIterator ptr1 = initial;
      RandomAccessIterator ptr2 = ptr1 + shift;
      while (ptr2 != initial) {
        *ptr1 = *ptr2;
        ptr1 = ptr2;
        if (last - ptr2 > shift)
          ptr2 += shift;
        else
          ptr2 = first + (shift - (last - ptr2));
      }
      *ptr1 = value;
    }
    
    template <class RandomAccessIterator, class Distance>
    void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
                  RandomAccessIterator last, Distance*,
                  random_access_iterator_tag) {
      Distance n = __gcd(last - first, middle - first);
      while (n--)
        __rotate_cycle(first, last, first + n, middle - first,
                       value_type(first));
    }
    
    // 将[first, middle)和[middle, last)内元素互换
    // 还是为了效率, 进行函数派发, 不解释了
    template <class ForwardIterator>
    inline void rotate(ForwardIterator first, ForwardIterator middle,
                       ForwardIterator last) {
      if (first == middle || middle == last) return;
      __rotate(first, middle, last, distance_type(first),
               iterator_category(first));
    }
    
    // 和rotate唯一的区别就是将旋转后的元素拷贝到新位置
    template <class ForwardIterator, class OutputIterator>
    OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
                               ForwardIterator last, OutputIterator result) {
      return copy(first, middle, copy(middle, last, result));
    }
    
    template <class RandomAccessIterator, class Distance>
    void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
                          Distance*) {
      if (first == last) return;
      for (RandomAccessIterator i = first + 1; i != last; ++i)
    #ifdef __STL_NO_DRAND48
        iter_swap(i, first + Distance(rand() % ((i - first) + 1)));
    #else
      iter_swap(i, first + Distance(lrand48() % ((i - first) + 1)));
    #endif
    }
    
    template <class RandomAccessIterator>
    inline void random_shuffle(RandomAccessIterator first,
                               RandomAccessIterator last) {
      __random_shuffle(first, last, distance_type(first));
    }
    
    // 产生随机的排列
    template <class RandomAccessIterator, class RandomNumberGenerator>
    void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
                        RandomNumberGenerator& rand)
    {
      if (first == last) return;
      for (RandomAccessIterator i = first + 1; i != last; ++i)
        iter_swap(i, first + rand((i - first) + 1));
    }
    
    template <class ForwardIterator, class OutputIterator, class Distance>
    OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
                                   OutputIterator out, const Distance n)
    {
      Distance remaining = 0;
      distance(first, last, remaining);
      Distance m = min(n, remaining);
    
      while (m > 0) {
    #ifdef __STL_NO_DRAND48
        if (rand() % remaining < m) {
    #else
        if (lrand48() % remaining < m) {
    #endif
          *out = *first;
          ++out;
          --m;
        }
    
        --remaining;
        ++first;
      }
      return out;
    }
    
    template <class ForwardIterator, class OutputIterator, class Distance,
              class RandomNumberGenerator>
    OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
                                   OutputIterator out, const Distance n,
                                   RandomNumberGenerator& rand)
    {
      Distance remaining = 0;
      distance(first, last, remaining);
      Distance m = min(n, remaining);
    
      while (m > 0) {
        if (rand(remaining) < m) {
          *out = *first;
          ++out;
          --m;
        }
    
        --remaining;
        ++first;
      }
      return out;
    }
    
    template <class InputIterator, class RandomAccessIterator, class Distance>
    RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
                                         RandomAccessIterator out,
                                         const Distance n)
    {
      Distance m = 0;
      Distance t = n;
      for ( ; first != last && m < n; ++m, ++first)
        out[m] = *first;
    
      while (first != last) {
        ++t;
    #ifdef __STL_NO_DRAND48
        Distance M = rand() % t;
    #else
        Distance M = lrand48() % t;
    #endif
        if (M < n)
          out[M] = *first;
        ++first;
      }
    
      return out + m;
    }
    
    template <class InputIterator, class RandomAccessIterator,
              class RandomNumberGenerator, class Distance>
    RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
                                         RandomAccessIterator out,
                                         RandomNumberGenerator& rand,
                                         const Distance n)
    {
      Distance m = 0;
      Distance t = n;
      for ( ; first != last && m < n; ++m, ++first)
        out[m] = *first;
    
      while (first != last) {
        ++t;
        Distance M = rand(t);
        if (M < n)
          out[M] = *first;
        ++first;
      }
    
      return out + m;
    }
    
    template <class InputIterator, class RandomAccessIterator>
    inline RandomAccessIterator
    random_sample(InputIterator first, InputIterator last,
                  RandomAccessIterator out_first, RandomAccessIterator out_last)
    {
      return __random_sample(first, last, out_first, out_last - out_first);
    }
    
    template <class InputIterator, class RandomAccessIterator,
              class RandomNumberGenerator>
    inline RandomAccessIterator
    random_sample(InputIterator first, InputIterator last,
                  RandomAccessIterator out_first, RandomAccessIterator out_last,
                  RandomNumberGenerator& rand)
    {
      return __random_sample(first, last, out_first, rand, out_last - out_first);
    }
    
    
    // 将[first, last)区间内元素重新排序, 所有满足判别式的元素都被放在前面
    template <class BidirectionalIterator, class Predicate>
    BidirectionalIterator partition(BidirectionalIterator first,
                                    BidirectionalIterator last, Predicate pred)
    {
      while (true) {
        while (true)
          if (first == last)
            return first;
          else if (pred(*first))
            ++first;
          else
            break;
        --last;
        while (true)
          if (first == last)
            return first;
          else if (!pred(*last))
            --last;
          else
            break;
        iter_swap(first, last);
        ++first;
      }
    }
    
    template <class ForwardIterator, class Predicate, class Distance>
    ForwardIterator __inplace_stable_partition(ForwardIterator first,
                                               ForwardIterator last,
                                               Predicate pred, Distance len) {
      if (len == 1) return pred(*first) ? last : first;
      ForwardIterator middle = first;
      advance(middle, len / 2);
      ForwardIterator
        first_cut = __inplace_stable_partition(first, middle, pred, len / 2);
      ForwardIterator
        second_cut = __inplace_stable_partition(middle, last, pred,
                                                len - len / 2);
      rotate(first_cut, middle, second_cut);
      len = 0;
      distance(middle, second_cut, len);
      advance(first_cut, len);
      return first_cut;
    }
    
    template <class ForwardIterator, class Pointer, class Predicate,
              class Distance>
    ForwardIterator __stable_partition_adaptive(ForwardIterator first,
                                                ForwardIterator last,
                                                Predicate pred, Distance len,
                                                Pointer buffer,
                                                Distance buffer_size) {
      if (len <= buffer_size) {
        ForwardIterator result1 = first;
        Pointer result2 = buffer;
        for ( ; first != last ; ++first)
          if (pred(*first)) {
            *result1 = *first;
            ++result1;
          }
          else {
            *result2 = *first;
            ++result2;
          }
        copy(buffer, result2, result1);
        return result1;
      }
      else {
        ForwardIterator middle = first;
        advance(middle, len / 2);
        ForwardIterator first_cut =
          __stable_partition_adaptive(first, middle, pred, len / 2,
                                      buffer, buffer_size);
        ForwardIterator second_cut =
          __stable_partition_adaptive(middle, last, pred, len - len / 2,
                                      buffer, buffer_size);
    
        rotate(first_cut, middle, second_cut);
        len = 0;
        distance(middle, second_cut, len);
        advance(first_cut, len);
        return first_cut;
      }
    }
    
    template <class ForwardIterator, class Predicate, class T, class Distance>
    inline ForwardIterator __stable_partition_aux(ForwardIterator first,
                                                  ForwardIterator last,
                                                  Predicate pred, T*, Distance*) {
      temporary_buffer<ForwardIterator, T> buf(first, last);
      if (buf.size() > 0)
        return __stable_partition_adaptive(first, last, pred,
                                           Distance(buf.requested_size()),
                                           buf.begin(), buf.size());
      else
        return __inplace_stable_partition(first, last, pred,
                                          Distance(buf.requested_size()));
    }
    
    template <class ForwardIterator, class Predicate>
    inline ForwardIterator stable_partition(ForwardIterator first,
                                            ForwardIterator last,
                                            Predicate pred) {
      if (first == last)
        return first;
      else
        return __stable_partition_aux(first, last, pred,
                                      value_type(first), distance_type(first));
    }
    
    template <class RandomAccessIterator, class T>
    RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
                                               RandomAccessIterator last,
                                               T pivot) {
      while (true) {
        while (*first < pivot) ++first;
        --last;
        while (pivot < *last) --last;
        if (!(first < last)) return first;
        iter_swap(first, last);
        ++first;
      }
    }
    
    template <class RandomAccessIterator, class T, class Compare>
    RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
                                               RandomAccessIterator last,
                                               T pivot, Compare comp) {
      while (1) {
        while (comp(*first, pivot)) ++first;
        --last;
        while (comp(pivot, *last)) --last;
        if (!(first < last)) return first;
        iter_swap(first, last);
        ++first;
      }
    }
    
    const int __stl_threshold = 16;
    
    
    template <class RandomAccessIterator, class T>
    void __unguarded_linear_insert(RandomAccessIterator last, T value) {
      RandomAccessIterator next = last;
      --next;
      while (value < *next) {
        *last = *next;
        last = next;
        --next;
      }
      *last = value;
    }
    
    template <class RandomAccessIterator, class T, class Compare>
    void __unguarded_linear_insert(RandomAccessIterator last, T value,
                                   Compare comp) {
      RandomAccessIterator next = last;
      --next;
      while (comp(value , *next)) {
        *last = *next;
        last = next;
        --next;
      }
      *last = value;
    }
    
    template <class RandomAccessIterator, class T>
    inline void __linear_insert(RandomAccessIterator first,
                                RandomAccessIterator last, T*) {
      T value = *last;
      if (value < *first) {
        copy_backward(first, last, last + 1);
        *first = value;
      }
      else
        __unguarded_linear_insert(last, value);
    }
    
    template <class RandomAccessIterator, class T, class Compare>
    inline void __linear_insert(RandomAccessIterator first,
                                RandomAccessIterator last, T*, Compare comp) {
      T value = *last;
      if (comp(value, *first)) {
        copy_backward(first, last, last + 1);
        *first = value;
      }
      else
        __unguarded_linear_insert(last, value, comp);
    }
    
    template <class RandomAccessIterator>
    void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {
      if (first == last) return;
      for (RandomAccessIterator i = first + 1; i != last; ++i)
        __linear_insert(first, i, value_type(first));
    }
    
    template <class RandomAccessIterator, class Compare>
    void __insertion_sort(RandomAccessIterator first,
                          RandomAccessIterator last, Compare comp) {
      if (first == last) return;
      for (RandomAccessIterator i = first + 1; i != last; ++i)
        __linear_insert(first, i, value_type(first), comp);
    }
    
    template <class RandomAccessIterator, class T>
    void __unguarded_insertion_sort_aux(RandomAccessIterator first,
                                        RandomAccessIterator last, T*) {
      for (RandomAccessIterator i = first; i != last; ++i)
        __unguarded_linear_insert(i, T(*i));
    }
    
    template <class RandomAccessIterator>
    inline void __unguarded_insertion_sort(RandomAccessIterator first,
                                    RandomAccessIterator last) {
      __unguarded_insertion_sort_aux(first, last, value_type(first));
    }
    
    template <class RandomAccessIterator, class T, class Compare>
    void __unguarded_insertion_sort_aux(RandomAccessIterator first,
                                        RandomAccessIterator last,
                                        T*, Compare comp) {
      for (RandomAccessIterator i = first; i != last; ++i)
        __unguarded_linear_insert(i, T(*i), comp);
    }
    
    template <class RandomAccessIterator, class Compare>
    inline void __unguarded_insertion_sort(RandomAccessIterator first,
                                           RandomAccessIterator last,
                                           Compare comp) {
      __unguarded_insertion_sort_aux(first, last, value_type(first), comp);
    }
    
    template <class RandomAccessIterator>
    void __final_insertion_sort(RandomAccessIterator first,
                                RandomAccessIterator last) {
      if (last - first > __stl_threshold) {
        __insertion_sort(first, first + __stl_threshold);
        __unguarded_insertion_sort(first + __stl_threshold, last);
      }
      else
        __insertion_sort(first, last);
    }
    
    template <class RandomAccessIterator, class Compare>
    void __final_insertion_sort(RandomAccessIterator first,
                                RandomAccessIterator last, Compare comp) {
      if (last - first > __stl_threshold) {
        __insertion_sort(first, first + __stl_threshold, comp);
        __unguarded_insertion_sort(first + __stl_threshold, last, comp);
      }
      else
        __insertion_sort(first, last, comp);
    }
    
    template <class Size>
    inline Size __lg(Size n) {
      Size k;
      for (k = 0; n > 1; n >>= 1) ++k;
      return k;
    }
    
    template <class RandomAccessIterator, class T, class Size>
    void __introsort_loop(RandomAccessIterator first,
                          RandomAccessIterator last, T*,
                          Size depth_limit) {
      while (last - first > __stl_threshold) {
        if (depth_limit == 0) {
          partial_sort(first, last, last);
          return;
        }
        --depth_limit;
        RandomAccessIterator cut = __unguarded_partition
          (first, last, T(__median(*first, *(first + (last - first)/2),
                                   *(last - 1))));
        __introsort_loop(cut, last, value_type(first), depth_limit);
        last = cut;
      }
    }
    
    template <class RandomAccessIterator, class T, class Size, class Compare>
    void __introsort_loop(RandomAccessIterator first,
                          RandomAccessIterator last, T*,
                          Size depth_limit, Compare comp) {
      while (last - first > __stl_threshold) {
        if (depth_limit == 0) {
          partial_sort(first, last, last, comp);
          return;
        }
        --depth_limit;
        RandomAccessIterator cut = __unguarded_partition
          (first, last, T(__median(*first, *(first + (last - first)/2),
                                   *(last - 1), comp)), comp);
        __introsort_loop(cut, last, value_type(first), depth_limit, comp);
        last = cut;
      }
    }
    
    // 必须为随RandomAccessIterator, 排序算法要根据情况进行派发
    template <class RandomAccessIterator>
    inline void sort(RandomAccessIterator first, RandomAccessIterator last)
    {
      if (first != last) {
        __introsort_loop(first, last, value_type(first), __lg(last - first) * 2);
        __final_insertion_sort(first, last);
      }
    }
    
    template <class RandomAccessIterator, class Compare>
    inline void sort(RandomAccessIterator first, RandomAccessIterator last,
                     Compare comp) {
      if (first != last) {
        __introsort_loop(first, last, value_type(first), __lg(last - first) * 2,
                         comp);
        __final_insertion_sort(first, last, comp);
      }
    }
    
    
    template <class RandomAccessIterator>
    void __inplace_stable_sort(RandomAccessIterator first,
                               RandomAccessIterator last) {
      if (last - first < 15) {
        __insertion_sort(first, last);
        return;
      }
      RandomAccessIterator middle = first + (last - first) / 2;
      __inplace_stable_sort(first, middle);
      __inplace_stable_sort(middle, last);
      __merge_without_buffer(first, middle, last, middle - first, last - middle);
    }
    
    template <class RandomAccessIterator, class Compare>
    void __inplace_stable_sort(RandomAccessIterator first,
                               RandomAccessIterator last, Compare comp) {
      if (last - first < 15) {
        __insertion_sort(first, last, comp);
        return;
      }
      RandomAccessIterator middle = first + (last - first) / 2;
      __inplace_stable_sort(first, middle, comp);
      __inplace_stable_sort(middle, last, comp);
      __merge_without_buffer(first, middle, last, middle - first,
                             last - middle, comp);
    }
    
    template <class RandomAccessIterator1, class RandomAccessIterator2,
              class Distance>
    void __merge_sort_loop(RandomAccessIterator1 first,
                           RandomAccessIterator1 last,
                           RandomAccessIterator2 result, Distance step_size) {
      Distance two_step = 2 * step_size;
    
      while (last - first >= two_step) {
        result = merge(first, first + step_size,
                       first + step_size, first + two_step, result);
        first += two_step;
      }
    
      step_size = min(Distance(last - first), step_size);
      merge(first, first + step_size, first + step_size, last, result);
    }
    
    template <class RandomAccessIterator1, class RandomAccessIterator2,
              class Distance, class Compare>
    void __merge_sort_loop(RandomAccessIterator1 first,
                           RandomAccessIterator1 last,
                           RandomAccessIterator2 result, Distance step_size,
                           Compare comp) {
      Distance two_step = 2 * step_size;
    
      while (last - first >= two_step) {
        result = merge(first, first + step_size,
                       first + step_size, first + two_step, result, comp);
        first += two_step;
      }
      step_size = min(Distance(last - first), step_size);
    
      merge(first, first + step_size, first + step_size, last, result, comp);
    }
    
    const int __stl_chunk_size = 7;
    
    template <class RandomAccessIterator, class Distance>
    void __chunk_insertion_sort(RandomAccessIterator first,
                                RandomAccessIterator last, Distance chunk_size) {
      while (last - first >= chunk_size) {
        __insertion_sort(first, first + chunk_size);
        first += chunk_size;
      }
      __insertion_sort(first, last);
    }
    
    template <class RandomAccessIterator, class Distance, class Compare>
    void __chunk_insertion_sort(RandomAccessIterator first,
                                RandomAccessIterator last,
                                Distance chunk_size, Compare comp) {
      while (last - first >= chunk_size) {
        __insertion_sort(first, first + chunk_size, comp);
        first += chunk_size;
      }
      __insertion_sort(first, last, comp);
    }
    
    template <class RandomAccessIterator, class Pointer, class Distance>
    void __merge_sort_with_buffer(RandomAccessIterator first,
                                  RandomAccessIterator last,
                                  Pointer buffer, Distance*) {
      Distance len = last - first;
      Pointer buffer_last = buffer + len;
    
      Distance step_size = __stl_chunk_size;
      __chunk_insertion_sort(first, last, step_size);
    
      while (step_size < len) {
        __merge_sort_loop(first, last, buffer, step_size);
        step_size *= 2;
        __merge_sort_loop(buffer, buffer_last, first, step_size);
        step_size *= 2;
      }
    }
    
    template <class RandomAccessIterator, class Pointer, class Distance,
              class Compare>
    void __merge_sort_with_buffer(RandomAccessIterator first,
                                  RandomAccessIterator last, Pointer buffer,
                                  Distance*, Compare comp) {
      Distance len = last - first;
      Pointer buffer_last = buffer + len;
    
      Distance step_size = __stl_chunk_size;
      __chunk_insertion_sort(first, last, step_size, comp);
    
      while (step_size < len) {
        __merge_sort_loop(first, last, buffer, step_size, comp);
        step_size *= 2;
        __merge_sort_loop(buffer, buffer_last, first, step_size, comp);
        step_size *= 2;
      }
    }
    
    template <class RandomAccessIterator, class Pointer, class Distance>
    void __stable_sort_adaptive(RandomAccessIterator first,
                                RandomAccessIterator last, Pointer buffer,
                                Distance buffer_size) {
      Distance len = (last - first + 1) / 2;
      RandomAccessIterator middle = first + len;
      if (len > buffer_size) {
        __stable_sort_adaptive(first, middle, buffer, buffer_size);
        __stable_sort_adaptive(middle, last, buffer, buffer_size);
      } else {
        __merge_sort_with_buffer(first, middle, buffer, (Distance*)0);
        __merge_sort_with_buffer(middle, last, buffer, (Distance*)0);
      }
      __merge_adaptive(first, middle, last, Distance(middle - first),
                       Distance(last - middle), buffer, buffer_size);
    }
    
    template <class RandomAccessIterator, class Pointer, class Distance,
              class Compare>
    void __stable_sort_adaptive(RandomAccessIterator first,
                                RandomAccessIterator last, Pointer buffer,
                                Distance buffer_size, Compare comp) {
      Distance len = (last - first + 1) / 2;
      RandomAccessIterator middle = first + len;
      if (len > buffer_size) {
        __stable_sort_adaptive(first, middle, buffer, buffer_size,
                               comp);
        __stable_sort_adaptive(middle, last, buffer, buffer_size,
                               comp);
      } else {
        __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp);
        __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp);
      }
      __merge_adaptive(first, middle, last, Distance(middle - first),
                       Distance(last - middle), buffer, buffer_size,
                       comp);
    }
    
    template <class RandomAccessIterator, class T, class Distance>
    inline void __stable_sort_aux(RandomAccessIterator first,
                                  RandomAccessIterator last, T*, Distance*) {
      temporary_buffer<RandomAccessIterator, T> buf(first, last);
      if (buf.begin() == 0)
        __inplace_stable_sort(first, last);
      else
        __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()));
    }
    
    template <class RandomAccessIterator, class T, class Distance, class Compare>
    inline void __stable_sort_aux(RandomAccessIterator first,
                                  RandomAccessIterator last, T*, Distance*,
                                  Compare comp) {
      temporary_buffer<RandomAccessIterator, T> buf(first, last);
      if (buf.begin() == 0)
        __inplace_stable_sort(first, last, comp);
      else
        __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()),
                               comp);
    }
    
    template <class RandomAccessIterator>
    inline void stable_sort(RandomAccessIterator first,
                            RandomAccessIterator last) {
      __stable_sort_aux(first, last, value_type(first), distance_type(first));
    }
    
    template <class RandomAccessIterator, class Compare>
    inline void stable_sort(RandomAccessIterator first,
                            RandomAccessIterator last, Compare comp) {
      __stable_sort_aux(first, last, value_type(first), distance_type(first),
                        comp);
    }
    
    template <class RandomAccessIterator, class T>
    void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
                        RandomAccessIterator last, T*) {
      make_heap(first, middle);
      for (RandomAccessIterator i = middle; i < last; ++i)
        if (*i < *first)
          __pop_heap(first, middle, i, T(*i), distance_type(first));
      sort_heap(first, middle);
    }
    
    // 只保证[first, middle)有序, 效率至上时使用
    template <class RandomAccessIterator>
    inline void partial_sort(RandomAccessIterator first,
                             RandomAccessIterator middle,
                             RandomAccessIterator last)
    {
      __partial_sort(first, middle, last, value_type(first));
    }
    
    template <class RandomAccessIterator, class T, class Compare>
    void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
                        RandomAccessIterator last, T*, Compare comp) {
      make_heap(first, middle, comp);
      for (RandomAccessIterator i = middle; i < last; ++i)
        if (comp(*i, *first))
          __pop_heap(first, middle, i, T(*i), comp, distance_type(first));
      sort_heap(first, middle, comp);
    }
    
    template <class RandomAccessIterator, class Compare>
    inline void partial_sort(RandomAccessIterator first,
                             RandomAccessIterator middle,
                             RandomAccessIterator last, Compare comp) {
      __partial_sort(first, middle, last, value_type(first), comp);
    }
    
    template <class InputIterator, class RandomAccessIterator, class Distance,
              class T>
    RandomAccessIterator __partial_sort_copy(InputIterator first,
                                             InputIterator last,
                                             RandomAccessIterator result_first,
                                             RandomAccessIterator result_last,
                                             Distance*, T*) {
      if (result_first == result_last) return result_last;
      RandomAccessIterator result_real_last = result_first;
      while(first != last && result_real_last != result_last) {
        *result_real_last = *first;
        ++result_real_last;
        ++first;
      }
      make_heap(result_first, result_real_last);
      while (first != last) {
        if (*first < *result_first)
          __adjust_heap(result_first, Distance(0),
                        Distance(result_real_last - result_first), T(*first));
        ++first;
      }
      sort_heap(result_first, result_real_last);
      return result_real_last;
    }
    
    template <class InputIterator, class RandomAccessIterator>
    inline RandomAccessIterator
    partial_sort_copy(InputIterator first, InputIterator last,
                      RandomAccessIterator result_first,
                      RandomAccessIterator result_last) {
      return __partial_sort_copy(first, last, result_first, result_last,
                                 distance_type(result_first), value_type(first));
    }
    
    template <class InputIterator, class RandomAccessIterator, class Compare,
              class Distance, class T>
    RandomAccessIterator __partial_sort_copy(InputIterator first,
                                             InputIterator last,
                                             RandomAccessIterator result_first,
                                             RandomAccessIterator result_last,
                                             Compare comp, Distance*, T*) {
      if (result_first == result_last) return result_last;
      RandomAccessIterator result_real_last = result_first;
      while(first != last && result_real_last != result_last) {
        *result_real_last = *first;
        ++result_real_last;
        ++first;
      }
      make_heap(result_first, result_real_last, comp);
      while (first != last) {
        if (comp(*first, *result_first))
          __adjust_heap(result_first, Distance(0),
                        Distance(result_real_last - result_first), T(*first),
                        comp);
        ++first;
      }
      sort_heap(result_first, result_real_last, comp);
      return result_real_last;
    }
    
    template <class InputIterator, class RandomAccessIterator, class Compare>
    inline RandomAccessIterator
    partial_sort_copy(InputIterator first, InputIterator last,
                      RandomAccessIterator result_first,
                      RandomAccessIterator result_last, Compare comp) {
      return __partial_sort_copy(first, last, result_first, result_last, comp,
                                 distance_type(result_first), value_type(first));
    }
    
    template <class RandomAccessIterator, class T>
    void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                       RandomAccessIterator last, T*) {
      while (last - first > 3) {
        RandomAccessIterator cut = __unguarded_partition
          (first, last, T(__median(*first, *(first + (last - first)/2),
                                   *(last - 1))));
        if (cut <= nth)
          first = cut;
        else
          last = cut;
      }
      __insertion_sort(first, last);
    }
    
    template <class RandomAccessIterator>
    inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                            RandomAccessIterator last) {
      __nth_element(first, nth, last, value_type(first));
    }
    
    template <class RandomAccessIterator, class T, class Compare>
    void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                       RandomAccessIterator last, T*, Compare comp) {
      while (last - first > 3) {
        RandomAccessIterator cut = __unguarded_partition
          (first, last, T(__median(*first, *(first + (last - first)/2),
                                   *(last - 1), comp)), comp);
        if (cut <= nth)
          first = cut;
        else
          last = cut;
      }
      __insertion_sort(first, last, comp);
    }
    
    template <class RandomAccessIterator, class Compare>
    inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                     RandomAccessIterator last, Compare comp) {
      __nth_element(first, nth, last, value_type(first), comp);
    }
    
    template <class ForwardIterator, class T, class Distance>
    ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
                                  const T& value, Distance*,
                                  forward_iterator_tag) {
      Distance len = 0;
      distance(first, last, len);
      Distance half;
      ForwardIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first;
        advance(middle, half);
        if (*middle < value) {
          first = middle;
          ++first;
          len = len - half - 1;
        }
        else
          len = half;
      }
      return first;
    }
    
    template <class RandomAccessIterator, class T, class Distance>
    RandomAccessIterator __lower_bound(RandomAccessIterator first,
                                       RandomAccessIterator last, const T& value,
                                       Distance*, random_access_iterator_tag) {
      Distance len = last - first;
      Distance half;
      RandomAccessIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first + half;
        if (*middle < value) {
          first = middle + 1;
          len = len - half - 1;
        }
        else
          len = half;
      }
      return first;
    }
    
    // 用于有序区间, 返回第一个大于value的位置
    // 同样为了效率, 要进行函数派发
    template <class ForwardIterator, class T>
    inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
                                       const T& value)
    {
      return __lower_bound(first, last, value, distance_type(first),
                           iterator_category(first));
    }
    
    template <class ForwardIterator, class T, class Compare, class Distance>
    ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
                                  const T& value, Compare comp, Distance*,
                                  forward_iterator_tag) {
      Distance len = 0;
      distance(first, last, len);
      Distance half;
      ForwardIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first;
        advance(middle, half);
        if (comp(*middle, value)) {
          first = middle;
          ++first;
          len = len - half - 1;
        }
        else
          len = half;
      }
      return first;
    }
    
    template <class RandomAccessIterator, class T, class Compare, class Distance>
    RandomAccessIterator __lower_bound(RandomAccessIterator first,
                                       RandomAccessIterator last,
                                       const T& value, Compare comp, Distance*,
                                       random_access_iterator_tag) {
      Distance len = last - first;
      Distance half;
      RandomAccessIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first + half;
        if (comp(*middle, value)) {
          first = middle + 1;
          len = len - half - 1;
        }
        else
          len = half;
      }
      return first;
    }
    
    template <class ForwardIterator, class T, class Compare>
    inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
                                       const T& value, Compare comp) {
      return __lower_bound(first, last, value, comp, distance_type(first),
                           iterator_category(first));
    }
    
    template <class ForwardIterator, class T, class Distance>
    ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
                                  const T& value, Distance*,
                                  forward_iterator_tag) {
      Distance len = 0;
      distance(first, last, len);
      Distance half;
      ForwardIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first;
        advance(middle, half);
        if (value < *middle)
          len = half;
        else {
          first = middle;
          ++first;
          len = len - half - 1;
        }
      }
      return first;
    }
    
    template <class RandomAccessIterator, class T, class Distance>
    RandomAccessIterator __upper_bound(RandomAccessIterator first,
                                       RandomAccessIterator last, const T& value,
                                       Distance*, random_access_iterator_tag) {
      Distance len = last - first;
      Distance half;
      RandomAccessIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first + half;
        if (value < *middle)
          len = half;
        else {
          first = middle + 1;
          len = len - half - 1;
        }
      }
      return first;
    }
    
    template <class ForwardIterator, class T>
    inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
                                       const T& value) {
      return __upper_bound(first, last, value, distance_type(first),
                           iterator_category(first));
    }
    
    template <class ForwardIterator, class T, class Compare, class Distance>
    ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
                                  const T& value, Compare comp, Distance*,
                                  forward_iterator_tag) {
      Distance len = 0;
      distance(first, last, len);
      Distance half;
      ForwardIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first;
        advance(middle, half);
        if (comp(value, *middle))
          len = half;
        else {
          first = middle;
          ++first;
          len = len - half - 1;
        }
      }
      return first;
    }
    
    template <class RandomAccessIterator, class T, class Compare, class Distance>
    RandomAccessIterator __upper_bound(RandomAccessIterator first,
                                       RandomAccessIterator last,
                                       const T& value, Compare comp, Distance*,
                                       random_access_iterator_tag) {
      Distance len = last - first;
      Distance half;
      RandomAccessIterator middle;
    
      while (len > 0) {
        half = len >> 1;
        middle = first + half;
        if (comp(value, *middle))
          len = half;
        else {
          first = middle + 1;
          len = len - half - 1;
        }
      }
      return first;
    }
    
    template <class ForwardIterator, class T, class Compare>
    inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
                                       const T& value, Compare comp) {
      return __upper_bound(first, last, value, comp, distance_type(first),
                           iterator_category(first));
    }
    
    template <class ForwardIterator, class T, class Distance>
    pair<ForwardIterator, ForwardIterator>
    __equal_range(ForwardIterator first, ForwardIterator last, const T& value,
                  Distance*, forward_iterator_tag) {
      Distance len = 0;
      distance(first, last, len);
      Distance half;
      ForwardIterator middle, left, right;
    
      while (len > 0) {
        half = len >> 1;
        middle = first;
        advance(middle, half);
        if (*middle < value) {
          first = middle;
          ++first;
          len = len - half - 1;
        }
        else if (value < *middle)
          len = half;
        else {
          left = lower_bound(first, middle, value);
          advance(first, len);
          right = upper_bound(++middle, first, value);
          return pair<ForwardIterator, ForwardIterator>(left, right);
        }
      }
      return pair<ForwardIterator, ForwardIterator>(first, first);
    }
    
    template <class RandomAccessIterator, class T, class Distance>
    pair<RandomAccessIterator, RandomAccessIterator>
    __equal_range(RandomAccessIterator first, RandomAccessIterator last,
                  const T& value, Distance*, random_access_iterator_tag) {
      Distance len = last - first;
      Distance half;
      RandomAccessIterator middle, left, right;
    
      while (len > 0) {
        half = len >> 1;
        middle = first + half;
        if (*middle < value) {
          first = middle + 1;
          len = len - half - 1;
        }
        else if (value < *middle)
          len = half;
        else {
          left = lower_bound(first, middle, value);
          right = upper_bound(++middle, first + len, value);
          return pair<RandomAccessIterator, RandomAccessIterator>(left,
                                                                  right);
        }
      }
      return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
    }
    
    template <class ForwardIterator, class T>
    inline pair<ForwardIterator, ForwardIterator>
    equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
      return __equal_range(first, last, value, distance_type(first),
                           iterator_category(first));
    }
    
    template <class ForwardIterator, class T, class Compare, class Distance>
    pair<ForwardIterator, ForwardIterator>
    __equal_range(ForwardIterator first, ForwardIterator last, const T& value,
                  Compare comp, Distance*, forward_iterator_tag) {
      Distance len = 0;
      distance(first, last, len);
      Distance half;
      ForwardIterator middle, left, right;
    
      while (len > 0) {
        half = len >> 1;
        middle = first;
        advance(middle, half);
        if (comp(*middle, value)) {
          first = middle;
          ++first;
          len = len - half - 1;
        }
        else if (comp(value, *middle))
          len = half;
        else {
          left = lower_bound(first, middle, value, comp);
          advance(first, len);
          right = upper_bound(++middle, first, value, comp);
          return pair<ForwardIterator, ForwardIterator>(left, right);
        }
      }
      return pair<ForwardIterator, ForwardIterator>(first, first);
    }
    
    template <class RandomAccessIterator, class T, class Compare, class Distance>
    pair<RandomAccessIterator, RandomAccessIterator>
    __equal_range(RandomAccessIterator first, RandomAccessIterator last,
                  const T& value, Compare comp, Distance*,
                  random_access_iterator_tag) {
      Distance len = last - first;
      Distance half;
      RandomAccessIterator middle, left, right;
    
      while (len > 0) {
        half = len >> 1;
        middle = first + half;
        if (comp(*middle, value)) {
          first = middle + 1;
          len = len - half - 1;
        }
        else if (comp(value, *middle))
          len = half;
        else {
          left = lower_bound(first, middle, value, comp);
          right = upper_bound(++middle, first + len, value, comp);
          return pair<RandomAccessIterator, RandomAccessIterator>(left,
                                                                  right);
        }
      }
      return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
    }
    
    template <class ForwardIterator, class T, class Compare>
    inline pair<ForwardIterator, ForwardIterator>
    equal_range(ForwardIterator first, ForwardIterator last, const T& value,
                Compare comp) {
      return __equal_range(first, last, value, comp, distance_type(first),
                           iterator_category(first));
    }
    
    // 用于有序区间的二分查找, 不知道的赶快去学数据结构
    template <class ForwardIterator, class T>
    bool binary_search(ForwardIterator first, ForwardIterator last,
                       const T& value) {
      ForwardIterator i = lower_bound(first, last, value);
      return i != last && !(value < *i);
    }
    
    template <class ForwardIterator, class T, class Compare>
    bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
                       Compare comp) {
      ForwardIterator i = lower_bound(first, last, value, comp);
      return i != last && !comp(value, *i);
    }
    
    // 将两个有序区间合并起来, 并保证其也有序
    template <class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result)
    {
      while (first1 != last1 && first2 != last2) {
        if (*first2 < *first1) {
          *result = *first2;
          ++first2;
        }
        else {
          *result = *first1;
          ++first1;
        }
        ++result;
      }
      return copy(first2, last2, copy(first1, last1, result));
    }
    
    template <class InputIterator1, class InputIterator2, class OutputIterator,
              class Compare>
    OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result, Compare comp)
    {
      while (first1 != last1 && first2 != last2) {
        if (comp(*first2, *first1)) {
          *result = *first2;
          ++first2;
        }
        else {
          *result = *first1;
          ++first1;
        }
        ++result;
      }
      return copy(first2, last2, copy(first1, last1, result));
    }
    
    template <class BidirectionalIterator, class Distance>
    void __merge_without_buffer(BidirectionalIterator first,
                                BidirectionalIterator middle,
                                BidirectionalIterator last,
                                Distance len1, Distance len2) {
      if (len1 == 0 || len2 == 0) return;
      if (len1 + len2 == 2) {
        if (*middle < *first) iter_swap(first, middle);
        return;
      }
      BidirectionalIterator first_cut = first;
      BidirectionalIterator second_cut = middle;
      Distance len11 = 0;
      Distance len22 = 0;
      if (len1 > len2) {
        len11 = len1 / 2;
        advance(first_cut, len11);
        second_cut = lower_bound(middle, last, *first_cut);
        distance(middle, second_cut, len22);
      }
      else {
        len22 = len2 / 2;
        advance(second_cut, len22);
        first_cut = upper_bound(first, middle, *second_cut);
        distance(first, first_cut, len11);
      }
      rotate(first_cut, middle, second_cut);
      BidirectionalIterator new_middle = first_cut;
      advance(new_middle, len22);
      __merge_without_buffer(first, first_cut, new_middle, len11, len22);
      __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
                             len2 - len22);
    }
    
    template <class BidirectionalIterator, class Distance, class Compare>
    void __merge_without_buffer(BidirectionalIterator first,
                                BidirectionalIterator middle,
                                BidirectionalIterator last,
                                Distance len1, Distance len2, Compare comp) {
      if (len1 == 0 || len2 == 0) return;
      if (len1 + len2 == 2) {
        if (comp(*middle, *first)) iter_swap(first, middle);
        return;
      }
      BidirectionalIterator first_cut = first;
      BidirectionalIterator second_cut = middle;
      Distance len11 = 0;
      Distance len22 = 0;
      if (len1 > len2) {
        len11 = len1 / 2;
        advance(first_cut, len11);
        second_cut = lower_bound(middle, last, *first_cut, comp);
        distance(middle, second_cut, len22);
      }
      else {
        len22 = len2 / 2;
        advance(second_cut, len22);
        first_cut = upper_bound(first, middle, *second_cut, comp);
        distance(first, first_cut, len11);
      }
      rotate(first_cut, middle, second_cut);
      BidirectionalIterator new_middle = first_cut;
      advance(new_middle, len22);
      __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
      __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
                             len2 - len22, comp);
    }
    
    template <class BidirectionalIterator1, class BidirectionalIterator2,
              class Distance>
    BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,
                                             BidirectionalIterator1 middle,
                                             BidirectionalIterator1 last,
                                             Distance len1, Distance len2,
                                             BidirectionalIterator2 buffer,
                                             Distance buffer_size) {
      BidirectionalIterator2 buffer_end;
      if (len1 > len2 && len2 <= buffer_size) {
        buffer_end = copy(middle, last, buffer);
        copy_backward(first, middle, last);
        return copy(buffer, buffer_end, first);
      } else if (len1 <= buffer_size) {
        buffer_end = copy(first, middle, buffer);
        copy(middle, last, first);
        return copy_backward(buffer, buffer_end, last);
      } else  {
        rotate(first, middle, last);
        advance(first, len2);
        return first;
      }
    }
    
    template <class BidirectionalIterator1, class BidirectionalIterator2,
              class BidirectionalIterator3>
    BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
                                            BidirectionalIterator1 last1,
                                            BidirectionalIterator2 first2,
                                            BidirectionalIterator2 last2,
                                            BidirectionalIterator3 result) {
      if (first1 == last1) return copy_backward(first2, last2, result);
      if (first2 == last2) return copy_backward(first1, last1, result);
      --last1;
      --last2;
      while (true) {
        if (*last2 < *last1) {
          *--result = *last1;
          if (first1 == last1) return copy_backward(first2, ++last2, result);
          --last1;
        }
        else {
          *--result = *last2;
          if (first2 == last2) return copy_backward(first1, ++last1, result);
          --last2;
        }
      }
    }
    
    template <class BidirectionalIterator1, class BidirectionalIterator2,
              class BidirectionalIterator3, class Compare>
    BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
                                            BidirectionalIterator1 last1,
                                            BidirectionalIterator2 first2,
                                            BidirectionalIterator2 last2,
                                            BidirectionalIterator3 result,
                                            Compare comp) {
      if (first1 == last1) return copy_backward(first2, last2, result);
      if (first2 == last2) return copy_backward(first1, last1, result);
      --last1;
      --last2;
      while (true) {
        if (comp(*last2, *last1)) {
          *--result = *last1;
          if (first1 == last1) return copy_backward(first2, ++last2, result);
          --last1;
        }
        else {
          *--result = *last2;
          if (first2 == last2) return copy_backward(first1, ++last1, result);
          --last2;
        }
      }
    }
    
    template <class BidirectionalIterator, class Distance, class Pointer>
    void __merge_adaptive(BidirectionalIterator first,
                          BidirectionalIterator middle,
                          BidirectionalIterator last, Distance len1, Distance len2,
                          Pointer buffer, Distance buffer_size) {
      if (len1 <= len2 && len1 <= buffer_size) {
        Pointer end_buffer = copy(first, middle, buffer);
        merge(buffer, end_buffer, middle, last, first);
      }
      else if (len2 <= buffer_size) {
        Pointer end_buffer = copy(middle, last, buffer);
        __merge_backward(first, middle, buffer, end_buffer, last);
      }
      else {
        BidirectionalIterator first_cut = first;
        BidirectionalIterator second_cut = middle;
        Distance len11 = 0;
        Distance len22 = 0;
        if (len1 > len2) {
          len11 = len1 / 2;
          advance(first_cut, len11);
          second_cut = lower_bound(middle, last, *first_cut);
          distance(middle, second_cut, len22);
        }
        else {
          len22 = len2 / 2;
          advance(second_cut, len22);
          first_cut = upper_bound(first, middle, *second_cut);
          distance(first, first_cut, len11);
        }
        BidirectionalIterator new_middle =
          __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
                            len22, buffer, buffer_size);
        __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
                         buffer_size);
        __merge_adaptive(new_middle, second_cut, last, len1 - len11,
                         len2 - len22, buffer, buffer_size);
      }
    }
    
    template <class BidirectionalIterator, class Distance, class Pointer,
              class Compare>
    void __merge_adaptive(BidirectionalIterator first,
                          BidirectionalIterator middle,
                          BidirectionalIterator last, Distance len1, Distance len2,
                          Pointer buffer, Distance buffer_size, Compare comp) {
      if (len1 <= len2 && len1 <= buffer_size) {
        Pointer end_buffer = copy(first, middle, buffer);
        merge(buffer, end_buffer, middle, last, first, comp);
      }
      else if (len2 <= buffer_size) {
        Pointer end_buffer = copy(middle, last, buffer);
        __merge_backward(first, middle, buffer, end_buffer, last, comp);
      }
      else {
        BidirectionalIterator first_cut = first;
        BidirectionalIterator second_cut = middle;
        Distance len11 = 0;
        Distance len22 = 0;
        if (len1 > len2) {
          len11 = len1 / 2;
          advance(first_cut, len11);
          second_cut = lower_bound(middle, last, *first_cut, comp);
          distance(middle, second_cut, len22);
        }
        else {
          len22 = len2 / 2;
          advance(second_cut, len22);
          first_cut = upper_bound(first, middle, *second_cut, comp);
          distance(first, first_cut, len11);
        }
        BidirectionalIterator new_middle =
          __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
                            len22, buffer, buffer_size);
        __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
                         buffer_size, comp);
        __merge_adaptive(new_middle, second_cut, last, len1 - len11,
                         len2 - len22, buffer, buffer_size, comp);
      }
    }
    
    template <class BidirectionalIterator, class T, class Distance>
    inline void __inplace_merge_aux(BidirectionalIterator first,
                                    BidirectionalIterator middle,
                                    BidirectionalIterator last, T*, Distance*) {
      Distance len1 = 0;
      distance(first, middle, len1);
      Distance len2 = 0;
      distance(middle, last, len2);
    
      temporary_buffer<BidirectionalIterator, T> buf(first, last);
      if (buf.begin() == 0)
        __merge_without_buffer(first, middle, last, len1, len2);
      else
        __merge_adaptive(first, middle, last, len1, len2,
                         buf.begin(), Distance(buf.size()));
    }
    
    template <class BidirectionalIterator, class T, class Distance, class Compare>
    inline void __inplace_merge_aux(BidirectionalIterator first,
                                    BidirectionalIterator middle,
                                    BidirectionalIterator last, T*, Distance*,
                                    Compare comp) {
      Distance len1 = 0;
      distance(first, middle, len1);
      Distance len2 = 0;
      distance(middle, last, len2);
    
      temporary_buffer<BidirectionalIterator, T> buf(first, last);
      if (buf.begin() == 0)
        __merge_without_buffer(first, middle, last, len1, len2, comp);
      else
        __merge_adaptive(first, middle, last, len1, len2,
                         buf.begin(), Distance(buf.size()),
                         comp);
    }
    
    template <class BidirectionalIterator>
    inline void inplace_merge(BidirectionalIterator first,
                              BidirectionalIterator middle,
                              BidirectionalIterator last) {
      if (first == middle || middle == last) return;
      __inplace_merge_aux(first, middle, last, value_type(first),
                          distance_type(first));
    }
    
    template <class BidirectionalIterator, class Compare>
    inline void inplace_merge(BidirectionalIterator first,
                              BidirectionalIterator middle,
                              BidirectionalIterator last, Compare comp) {
      if (first == middle || middle == last) return;
      __inplace_merge_aux(first, middle, last, value_type(first),
                          distance_type(first), comp);
    }
    
    // 判断[first2, last2)是否包含在[first1, last1)中,
    // 注意: 两个区间要保证有序, 如果容器是降序排列, 那么要使用另一个版本,
    //       并使用greater<>()来比较
    template <class InputIterator1, class InputIterator2>
    bool includes(InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, InputIterator2 last2)
    {
      while (first1 != last1 && first2 != last2)
        if (*first2 < *first1)
          return false;
        else if(*first1 < *first2)
          ++first1;
        else
          ++first1, ++first2;
    
      return first2 == last2;
    }
    
    // 除了自己指定判别式, 其余同上
    template <class InputIterator1, class InputIterator2, class Compare>
    bool includes(InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, InputIterator2 last2, Compare comp)
    {
      while (first1 != last1 && first2 != last2)
        if (comp(*first2, *first1))
          return false;
        else if(comp(*first1, *first2))
          ++first1;
        else
          ++first1, ++first2;
    
      return first2 == last2;
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    // 四个集合相关算法
    ////////////////////////////////////////////////////////////////////////////////
    
    // 求两个集合的的并集, 和数学定义的并集有一些不一样
    // 对于两个集合S1[first1, last1)和S2[first2, last2)
    // 假设其中k元素在S1中出现n1次, 在S2中出现n2次
    // 那么求出的并集选取max(n1, n2)为并集内k元素个数
    // 注意: 集合相关操作均要求区间有序, 后面不再强调
    template <class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             OutputIterator result)
    {
      // 先进行历遍操作
      while (first1 != last1 && first2 != last2) {
        // 这里把现在能确定的并集先加入到result中
        // 先把较小的加入到结果中, 否则如果相等, 那么也要加入
        if (*first1 < *first2) {
          *result = *first1;
          ++first1;
        }
        else if (*first2 < *first1) {
          *result = *first2;
          ++first2;
        }
        else {
          *result = *first1;
          ++first1;
          ++first2;
        }
        ++result;
      }
    
      // 将剩余的元素加入到并集中
      return copy(first2, last2, copy(first1, last1, result));
    }
    
    // 使用用户指定的二元比较判别式, 其余同上面
    template <class InputIterator1, class InputIterator2, class OutputIterator,
              class Compare>
    OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             OutputIterator result, Compare comp)
    {
      while (first1 != last1 && first2 != last2) {
        if (comp(*first1, *first2)) {
          *result = *first1;
          ++first1;
        }
        else if (comp(*first2, *first1)) {
          *result = *first2;
          ++first2;
        }
        else {
          *result = *first1;
          ++first1;
          ++first2;
        }
        ++result;
      }
      return copy(first2, last2, copy(first1, last1, result));
    }
    
    // 求两个集合的的交集, 和数学定义的并集有一些不一样
    // 对于两个集合S1[first1, last1)和S2[first2, last2)
    // 假设其中k元素在S1中出现n1次, 在S2中出现n2次
    // 那么求出的交集选取min(n1, n2)为交集内k元素个数
    template <class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
                                    InputIterator2 first2, InputIterator2 last2,
                                    OutputIterator result)
    {
      // 算法很简单, 不进行说明
      while (first1 != last1 && first2 != last2)
        if (*first1 < *first2)
          ++first1;
        else if (*first2 < *first1)
          ++first2;
        else {
          *result = *first1;
          ++first1;
          ++first2;
          ++result;
        }
      return result;
    }
    
    // 使用用户指定的二元比较判别式, 其余同上面
    template <class InputIterator1, class InputIterator2, class OutputIterator,
              class Compare>
    OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
                                    InputIterator2 first2, InputIterator2 last2,
                                    OutputIterator result, Compare comp)
    {
      while (first1 != last1 && first2 != last2)
        if (comp(*first1, *first2))
          ++first1;
        else if (comp(*first2, *first1))
          ++first2;
        else {
          *result = *first1;
          ++first1;
          ++first2;
          ++result;
        }
      return result;
    }
    
    // 求两个集合的的差集, 和数学定义的并集有一些不一样
    // 对于两个集合S1[first1, last1)和S2[first2, last2)
    // 假设其中k元素在S1中出现n1次, 在S2中出现n2次
    // 那么求出的差集选取max(n1 - n2, 0)为差集内k元素个数
    template <class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                                  InputIterator2 first2, InputIterator2 last2,
                                  OutputIterator result)
    {
      while (first1 != last1 && first2 != last2)
        if (*first1 < *first2) {    // 找到了一个合适的元素, 加入到结果中
          *result = *first1;        // 向后调整迭代器
          ++first1;
          ++result;
        }
        else if (*first2 < *first1) // 元素不合适, 调整迭代器
          ++first2;
        else {                      // 这个用来处理出现相同元素的情况
          ++first1;
          ++first2;
        }
    
      // 将剩余的元素加入到结果中
      return copy(first1, last1, result);
    }
    
    // 使用用户指定的二元比较判别式, 其余同上面
    template <class InputIterator1, class InputIterator2, class OutputIterator,
              class Compare>
    OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                                  InputIterator2 first2, InputIterator2 last2,
                                  OutputIterator result, Compare comp) {
      while (first1 != last1 && first2 != last2)
        if (comp(*first1, *first2)) {
          *result = *first1;
          ++first1;
          ++result;
        }
        else if (comp(*first2, *first1))
          ++first2;
        else {
          ++first1;
          ++first2;
        }
      return copy(first1, last1, result);
    }
    
    // 求两个集合的的对称差集, 和数学定义的并集有一些不一样
    // 其用公式可以表示为(S1 - S2) U (S2 - S1)
    // 对于两个集合S1[first1, last1)和S2[first2, last2)
    // 假设其中k元素在S1中出现n1次, 在S2中出现n2次
    // 那么结果中会出现|n1 - n2|个k元素
    template <class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_symmetric_difference(InputIterator1 first1,
                                            InputIterator1 last1,
                                            InputIterator2 first2,
                                            InputIterator2 last2,
                                            OutputIterator result)
    {
      // 算法和上面的差不多, 不解释
      while (first1 != last1 && first2 != last2)
        if (*first1 < *first2) {
          *result = *first1;
          ++first1;
          ++result;
        }
        else if (*first2 < *first1) {
          *result = *first2;
          ++first2;
          ++result;
        }
        else {
          ++first1;
          ++first2;
        }
    
      return copy(first2, last2, copy(first1, last1, result));
    }
    
    // 使用用户指定的二元比较判别式, 其余同上面
    template <class InputIterator1, class InputIterator2, class OutputIterator,
              class Compare>
    OutputIterator set_symmetric_difference(InputIterator1 first1,
                                            InputIterator1 last1,
                                            InputIterator2 first2,
                                            InputIterator2 last2,
                                            OutputIterator result, Compare comp)
    {
      while (first1 != last1 && first2 != last2)
        if (comp(*first1, *first2)) {
          *result = *first1;
          ++first1;
          ++result;
        }
        else if (comp(*first2, *first1)) {
          *result = *first2;
          ++first2;
          ++result;
        }
        else {
          ++first1;
          ++first2;
        }
      return copy(first2, last2, copy(first1, last1, result));
    }
    
    // 查找指定区间内最大的元素
    template <class ForwardIterator>
    ForwardIterator max_element(ForwardIterator first, ForwardIterator last)
    {
      if (first == last) return first;
      ForwardIterator result = first;
      while (++first != last)
        if (*result < *first) result = first;
      return result;
    }
    
    // 使用用户指定的二元比较判别式, 其余同上面
    template <class ForwardIterator, class Compare>
    ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
                                Compare comp)
    {
      if (first == last) return first;
      ForwardIterator result = first;
      while (++first != last)
        if (comp(*result, *first)) result = first;
      return result;
    }
    
    // 查找指定区间内最小的元素
    template <class ForwardIterator>
    ForwardIterator min_element(ForwardIterator first, ForwardIterator last)
    {
      if (first == last) return first;
      ForwardIterator result = first;
      while (++first != last)
        if (*first < *result) result = first;
      return result;
    }
    
    template <class ForwardIterator, class Compare>
    ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
                                Compare comp)
                                {
      if (first == last) return first;
      ForwardIterator result = first;
      while (++first != last)
        if (comp(*first, *result)) result = first;
      return result;
    }
    
    // 获取下一个全排列
    template <class BidirectionalIterator>
    bool next_permutation(BidirectionalIterator first,
                          BidirectionalIterator last)
    {
      if (first == last) return false;
      BidirectionalIterator i = first;
      ++i;
      if (i == last) return false;
      i = last;
      --i;
    
      for(;;) {
        BidirectionalIterator ii = i;
        --i;
        if (*i < *ii) {
          BidirectionalIterator j = last;
          while (!(*i < *--j));
          iter_swap(i, j);
          reverse(ii, last);
          return true;
        }
        if (i == first) {
          reverse(first, last);
          return false;
        }
      }
    }
    
    template <class BidirectionalIterator, class Compare>
    bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
                          Compare comp) {
      if (first == last) return false;
      BidirectionalIterator i = first;
      ++i;
      if (i == last) return false;
      i = last;
      --i;
    
      for(;;) {
        BidirectionalIterator ii = i;
        --i;
        if (comp(*i, *ii)) {
          BidirectionalIterator j = last;
          while (!comp(*i, *--j));
          iter_swap(i, j);
          reverse(ii, last);
          return true;
        }
        if (i == first) {
          reverse(first, last);
          return false;
        }
      }
    }
    
    template <class BidirectionalIterator>
    bool prev_permutation(BidirectionalIterator first,
                          BidirectionalIterator last) {
      if (first == last) return false;
      BidirectionalIterator i = first;
      ++i;
      if (i == last) return false;
      i = last;
      --i;
    
      for(;;) {
        BidirectionalIterator ii = i;
        --i;
        if (*ii < *i) {
          BidirectionalIterator j = last;
          while (!(*--j < *i));
          iter_swap(i, j);
          reverse(ii, last);
          return true;
        }
        if (i == first) {
          reverse(first, last);
          return false;
        }
      }
    }
    
    // 获取前一个全排列
    template <class BidirectionalIterator, class Compare>
    bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
                          Compare comp) {
      if (first == last) return false;
      BidirectionalIterator i = first;
      ++i;
      if (i == last) return false;
      i = last;
      --i;
    
      for(;;) {
        BidirectionalIterator ii = i;
        --i;
        if (comp(*ii, *i)) {
          BidirectionalIterator j = last;
          while (!comp(*--j, *i));
          iter_swap(i, j);
          reverse(ii, last);
          return true;
        }
        if (i == first) {
          reverse(first, last);
          return false;
        }
      }
    }
    
    // 在区间[first1, last1)内查找区间[first2, last2)第一次出现的位置
    template <class InputIterator, class ForwardIterator>
    InputIterator find_first_of(InputIterator first1, InputIterator last1,
                                ForwardIterator first2, ForwardIterator last2)
    {
      for ( ; first1 != last1; ++first1)
        for (ForwardIterator iter = first2; iter != last2; ++iter)
          if (*first1 == *iter)
            return first1;
      return last1;
    }
    
    // 使用用户指定的判别式, 其余同上面
    template <class InputIterator, class ForwardIterator, class BinaryPredicate>
    InputIterator find_first_of(InputIterator first1, InputIterator last1,
                                ForwardIterator first2, ForwardIterator last2,
                                BinaryPredicate comp)
    {
      for ( ; first1 != last1; ++first1)
        for (ForwardIterator iter = first2; iter != last2; ++iter)
          if (comp(*first1, *iter))
            return first1;
      return last1;
    }
    
    
    // Search [first2, last2) as a subsequence in [first1, last1).
    
    // find_end for forward iterators.
    template <class ForwardIterator1, class ForwardIterator2>
    ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
                                ForwardIterator2 first2, ForwardIterator2 last2,
                                forward_iterator_tag, forward_iterator_tag)
    {
      if (first2 == last2)  // 如果查找的目标区间为空, 那么就返回last1
        return last1;
      else {
        ForwardIterator1 result = last1;
        while (1) {
          // 查找匹配区间
          ForwardIterator1 new_result = search(first1, last1, first2, last2);
          if (new_result == last1)  // 没找到
            return result;
          else {    // 找到了, 准备看后面还有没有匹配区间
            result = new_result;
            first1 = new_result;
            ++first1;
          }
        }
      }
    }
    
    template <class ForwardIterator1, class ForwardIterator2,
              class BinaryPredicate>
    ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
                                ForwardIterator2 first2, ForwardIterator2 last2,
                                forward_iterator_tag, forward_iterator_tag,
                                BinaryPredicate comp)
    {
      if (first2 == last2)
        return last1;
      else {
        ForwardIterator1 result = last1;
        while (1) {
          ForwardIterator1 new_result = search(first1, last1, first2, last2, comp);
          if (new_result == last1)
            return result;
          else {
            result = new_result;
            first1 = new_result;
            ++first1;
          }
        }
      }
    }
    
    // find_end for bidirectional iterators.  Requires partial specialization.
    #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
    
    template <class BidirectionalIterator1, class BidirectionalIterator2>
    BidirectionalIterator1
    __find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
               BidirectionalIterator2 first2, BidirectionalIterator2 last2,
               bidirectional_iterator_tag, bidirectional_iterator_tag)
    {
      typedef reverse_iterator<BidirectionalIterator1> reviter1;
      typedef reverse_iterator<BidirectionalIterator2> reviter2;
    
      reviter1 rlast1(first1);
      reviter2 rlast2(first2);
      reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2);
    
      if (rresult == rlast1)
        return last1;
      else {
        BidirectionalIterator1 result = rresult.base();
        advance(result, -distance(first2, last2));
        return result;
      }
    }
    
    // 可以逆向查找, 速度块
    template <class BidirectionalIterator1, class BidirectionalIterator2,
              class BinaryPredicate>
    BidirectionalIterator1
    __find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
               BidirectionalIterator2 first2, BidirectionalIterator2 last2,
               bidirectional_iterator_tag, bidirectional_iterator_tag,
               BinaryPredicate comp)
    {
      typedef reverse_iterator<BidirectionalIterator1> reviter1;
      typedef reverse_iterator<BidirectionalIterator2> reviter2;
    
      reviter1 rlast1(first1);
      reviter2 rlast2(first2);
      reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2,
                                comp);
    
      if (rresult == rlast1)
        return last1;
      else {
        BidirectionalIterator1 result = rresult.base();
        advance(result, -distance(first2, last2));
        return result;
      }
    }
    #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
    
    // 在区间[first1, last1)内查找区间[first2, last2)最后一次出现的位置
    template <class ForwardIterator1, class ForwardIterator2>
    inline ForwardIterator1
    find_end(ForwardIterator1 first1, ForwardIterator1 last1,
             ForwardIterator2 first2, ForwardIterator2 last2)
    {
    // 这里根据是否能逆向查找来派发函数
    #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
      typedef typename iterator_traits<ForwardIterator1>::iterator_category
              category1;
      typedef typename iterator_traits<ForwardIterator2>::iterator_category
              category2;
      return __find_end(first1, last1, first2, last2, category1(), category2());
    #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
      return __find_end(first1, last1, first2, last2,
                        forward_iterator_tag(), forward_iterator_tag());
    #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
    }
    
    // 使用用户指定的判别式, 其余同上面
    template <class ForwardIterator1, class ForwardIterator2,
              class BinaryPredicate>
    inline ForwardIterator1
    find_end(ForwardIterator1 first1, ForwardIterator1 last1,
             ForwardIterator2 first2, ForwardIterator2 last2,
             BinaryPredicate comp)
    {
    #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
      typedef typename iterator_traits<ForwardIterator1>::iterator_category
              category1;
      typedef typename iterator_traits<ForwardIterator2>::iterator_category
              category2;
      return __find_end(first1, last1, first2, last2, category1(), category2(),
                        comp);
    #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
      return __find_end(first1, last1, first2, last2,
                        forward_iterator_tag(), forward_iterator_tag(),
                        comp);
    #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
    }
    
    template <class RandomAccessIterator, class Distance>
    bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
                   Distance*)
    {
      const Distance n = last - first;
    
      Distance parent = 0;
      for (Distance child = 1; child < n; ++child) {
        if (first[parent] < first[child])
          return false;
        if ((child & 1) == 0)
          ++parent;
      }
      return true;
    }
    
    template <class RandomAccessIterator>
    inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
    {
      return __is_heap(first, last, distance_type(first));
    }
    
    
    template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>
    bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
                   StrictWeakOrdering comp,
                   Distance*)
    {
      const Distance n = last - first;
    
      Distance parent = 0;
      for (Distance child = 1; child < n; ++child) {
        if (comp(first[parent], first[child]))
          return false;
        if ((child & 1) == 0)
          ++parent;
      }
      return true;
    }
    
    template <class RandomAccessIterator, class StrictWeakOrdering>
    inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
                        StrictWeakOrdering comp)
    {
      return __is_heap(first, last, comp, distance_type(first));
    }
    
    
    template <class ForwardIterator>
    bool is_sorted(ForwardIterator first, ForwardIterator last)
    {
      if (first == last)
        return true;
    
      ForwardIterator next = first;
      for (++next; next != last; first = next, ++next) {
        if (*next < *first)
          return false;
      }
    
      return true;
    }
    
    template <class ForwardIterator, class StrictWeakOrdering>
    bool is_sorted(ForwardIterator first, ForwardIterator last,
                   StrictWeakOrdering comp)
    {
      if (first == last)
        return true;
    
      ForwardIterator next = first;
      for (++next; next != last; first = next, ++next) {
        if (comp(*next, *first))
          return false;
      }
    
      return true;
    }
    
    #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
    #pragma reset woff 1209
    #endif
    
    __STL_END_NAMESPACE
    
    #endif /* __SGI_STL_INTERNAL_ALGO_H */
    
    // Local Variables:
    // mode:C++
    // End:
  • 相关阅读:
    OpenGL完整实例
    OpenGL
    Socket(2)
    Socket(1)
    Stream,Reader/Writer,Buffered的区别(2)
    Stream,Reader/Writer,Buffered的区别(1)
    SQLite数据库与Contentprovider(2)
    SQLite数据库与Contentprovider(1)
    数据存储和访问
    AIDL与service
  • 原文地址:https://www.cnblogs.com/zendu/p/4981576.html
Copyright © 2020-2023  润新知