#include #define QS_SWAP(a,b) {t = (a); (a) = (b); (b) = t; } template void MySort(T *begin, T *end) { size_t count = end - begin, count2; T *right_ptr = begin + count - 1; T *left_ptr = begin; if (count <= 1) return; T t; struct Stack { T *left, *right; size_t count; }; Stack stack[64], *sp = stack + 62; sp[1].count = 0; do { while (count > 1) { if (count == 2) { if (*right_ptr < *left_ptr) QS_SWAP(*left_ptr, *right_ptr); break; } T *mid_ptr = &left_ptr[count >> 1]; if (*mid_ptr < *left_ptr) { if (*mid_ptr < *right_ptr) { if (*left_ptr < *right_ptr) { QS_SWAP(*mid_ptr, *left_ptr); } else { QS_SWAP(*mid_ptr, *left_ptr); QS_SWAP(*mid_ptr, *right_ptr); } } else { QS_SWAP(*left_ptr, *right_ptr); } } else { if (*right_ptr < *mid_ptr) { if (*left_ptr < *right_ptr) { QS_SWAP(*mid_ptr, *right_ptr); } else { QS_SWAP(*left_ptr, *mid_ptr); QS_SWAP(*left_ptr, *right_ptr); } } } if (count <= 4) { if (count == 4) { if (*mid_ptr < left_ptr[1]) { if (left_ptr[1] < right_ptr[0]) { QS_SWAP(left_ptr[1], *mid_ptr); } else { QS_SWAP(left_ptr[1], *mid_ptr); QS_SWAP(*mid_ptr, *right_ptr); } } else { if (left_ptr[1] < left_ptr[0]) { QS_SWAP(*left_ptr, left_ptr[1]); } } } break; } QS_SWAP(*left_ptr, *mid_ptr); T *x_ptr = left_ptr; T *y_ptr = right_ptr; for (;;) { do y_ptr--; while (*left_ptr < *y_ptr); if (y_ptr <= x_ptr) break; do x_ptr++; while (*x_ptr < *left_ptr); if (x_ptr >= y_ptr) { x_ptr--; break; } QS_SWAP(*x_ptr, *y_ptr); } QS_SWAP(*x_ptr, *left_ptr); T *z_ptr = x_ptr; do z_ptr++; while (z_ptr < right_ptr && !(*x_ptr < *z_ptr)); T *w_ptr = x_ptr; do w_ptr--; while (w_ptr > left_ptr && !(*w_ptr < *x_ptr)); count = right_ptr - z_ptr + 1; count2 = w_ptr - left_ptr + 1; assert(!(count & 0x80000000)); assert(!(count2 & 0x80000000)); if (count >= count2) { sp->left = left_ptr; sp->right = w_ptr; sp->count = count2; left_ptr = z_ptr; } else { sp->left = z_ptr; sp->right = right_ptr; sp->count = count; right_ptr = w_ptr; count = count2; } sp--; } count = sp[1].count; left_ptr = sp[1].left; right_ptr = sp[1].right; sp++; } while (count); } #undef QS_SWAP template void MyMakeHeap(T *begin, T *end) { size_t n = end - begin, t, u; for (size_t half = n >> 1; half--; ) { for (t = half; (u = 2 * t + 1) < n; t = u) { if (u + 1 < n && begin[u] < begin[u + 1]) u++; if (begin[u] < begin[t]) break; std::swap(begin[t], begin[u]); } } } template void MyPushHeap(T *begin, T *end) { size_t t = --end - begin, u; while (t) { u = (t - 1) >> 1; if (!(begin[u] < begin[t])) break; std::swap(begin[t], begin[u]); t = u; } } template void MyPopHeap(T *begin, T *end) { size_t n = end - begin; size_t t = 0, u; for (; (u = 2 * t + 1) < n; t = u) { if (u + 1 < n && begin[u] < begin[u + 1]) u++; begin[t] = begin[u]; } if (t < n - 1) { begin[t] = begin[n - 1]; MyPushHeap(begin, begin + t + 1); } } template void SimpleSort(T *p, T *pend) { if (p != pend) { for (T *lp = p + 1, *rp; lp != pend; lp++) { T t = lp[0]; for (rp = lp; rp > p && t < rp[-1]; rp--) rp[0] = rp[-1]; rp[0] = t; } } }