#pragma once #include #include #include #include #include void sort_pair(std::pair* pairs, size_t len); void sort_pairs(std::pair* pairs, size_t len); template std::pair* create_pairs(const T& array, size_t len) { std::pair* pairs = new std::pair[len]; for (size_t i = 0; i < len; i++) { pairs[i].second = array[i * 2]; if (array.size() > i * 2 + 1) pairs[i].first = array[i * 2 + 1]; } if (len % 2) pairs[len - 1].first = pairs[len - 1].second; return pairs; } template size_t binary_search(const T& array, size_t start, size_t end, int value) { if (array[end] < value) return end; while (true) { int mid = start + ((end - start) / 2); int min_value = array[mid]; if (min_value == value || end - start <= 1) { if (min_value < value) return mid + 1; return mid; } else if (min_value < value) start = mid; else if (min_value > value) end = mid; } } template void insert_sort(const std::pair* pairs, size_t len, T& array) { for (size_t i = 1; i < len; i++) { array.push_back(pairs[i].first); if (pairs[i].first == pairs[i].second) continue; size_t index = binary_search(array, 0, array.size() - 1, pairs[i].second); array.insert(array.begin() + index, pairs[i].second); } } template void PmergeMe(T& array) { if (array.size() < 2) return; std::size_t len = array.size() / 2 + array.size() % 2; std::pair* pairs = create_pairs(array, len); sort_pair(pairs, len); sort_pairs(pairs, len); array.clear(); array.push_back(pairs[0].second); if (pairs[0].second != pairs[0].first) array.push_back(pairs[0].first); insert_sort(pairs, len, array); delete[] pairs; }