stl_algo.h

来源:互联网 发布:sys.stdin.read 知乎 编辑:程序博客网 时间:2024/06/06 08:34
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_SPECIALIZATIONtemplate <class InputIterator, class T>typename iterator_traits<InputIterator>::difference_typecount(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_typecount_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 RandomAccessIteratorrandom_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 RandomAccessIteratorrandom_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 RandomAccessIteratorpartial_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 RandomAccessIteratorpartial_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_SPECIALIZATIONtemplate <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 ForwardIterator1find_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 ForwardIterator1find_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:

0 0
原创粉丝点击