#include <iostream>
#include <vector>
#include <random>
#include <chrono>
#include <algorithm>
struct A {
A(int i = 0) : i(i) {}
int i;
static int nSwaps;
friend void swap(A& l, A& r)
{
++nSwaps;
std::swap(l.i, r.i);
}
bool operator<(const A& r) const
{
return i < r.i;
}
};
int A::nSwaps = 0;
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::milliseconds;
int main()
{
std::vector<A> v(10000000);
std::ranlux24_base gen(std::random_device{}());
std::generate(v.begin(), v.end(), [&gen]() {return gen();});
auto s = high_resolution_clock::now();
std::sort(v.begin(), v.end());
std::cout << duration_cast<milliseconds>(high_resolution_clock::now() - s).count()
<< "ms with " << A::nSwaps << " swaps\n";
A::nSwaps = 0;
s = high_resolution_clock::now();
std::shuffle(v.begin(), v.end(), gen);
std::cout << duration_cast<milliseconds>(high_resolution_clock::now() - s).count()
<< "ms with " << A::nSwaps << " swaps\n";
}
ICAgICNpbmNsdWRlIDxpb3N0cmVhbT4KCiAgICAjaW5jbHVkZSA8dmVjdG9yPgogICAgI2luY2x1ZGUgPHJhbmRvbT4KICAgICNpbmNsdWRlIDxjaHJvbm8+CiAgICAjaW5jbHVkZSA8YWxnb3JpdGhtPgoKICAgIHN0cnVjdCBBIHsKICAgICAgICBBKGludCBpID0gMCkgOiBpKGkpIHt9CiAgICAgICAgaW50IGk7CiAgICAgICAgc3RhdGljIGludCBuU3dhcHM7CgogICAgICAgIGZyaWVuZCB2b2lkIHN3YXAoQSYgbCwgQSYgcikKICAgICAgICB7CiAgICAgICAgICAgICsrblN3YXBzOwogICAgICAgICAgICBzdGQ6OnN3YXAobC5pLCByLmkpOwogICAgICAgIH0KCiAgICAgICAgYm9vbCBvcGVyYXRvcjwoY29uc3QgQSYgcikgY29uc3QKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBpIDwgci5pOwogICAgICAgIH0KICAgIH07CgogICAgaW50IEE6Om5Td2FwcyA9IDA7CgogICAgdXNpbmcgc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazsKICAgIHVzaW5nIHN0ZDo6Y2hyb25vOjpkdXJhdGlvbl9jYXN0OwogICAgdXNpbmcgc3RkOjpjaHJvbm86Om1pbGxpc2Vjb25kczsKCgogICAgaW50IG1haW4oKQogICAgewogICAgICAgIHN0ZDo6dmVjdG9yPEE+IHYoMTAwMDAwMDApOwogICAgCiAgICAgICAgc3RkOjpyYW5sdXgyNF9iYXNlIGdlbihzdGQ6OnJhbmRvbV9kZXZpY2V7fSgpKTsKICAgICAgICBzdGQ6OmdlbmVyYXRlKHYuYmVnaW4oKSwgdi5lbmQoKSwgWyZnZW5dKCkge3JldHVybiBnZW4oKTt9KTsKICAgIAogICAgICAgIGF1dG8gcyA9IGhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7CiAgICAgICAgc3RkOjpzb3J0KHYuYmVnaW4oKSwgdi5lbmQoKSk7CiAgICAgICAgc3RkOjpjb3V0IDw8IGR1cmF0aW9uX2Nhc3Q8bWlsbGlzZWNvbmRzPihoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpIC0gcykuY291bnQoKSAKICAgICAgICAgICAgPDwgIm1zIHdpdGggIiA8PCBBOjpuU3dhcHMgPDwgIiBzd2Fwc1xuIjsKICAgIAogICAgICAgIEE6Om5Td2FwcyA9IDA7CiAgICAgICAgcyA9IGhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7CiAgICAgICAgc3RkOjpzaHVmZmxlKHYuYmVnaW4oKSwgdi5lbmQoKSwgZ2VuKTsKICAgICAgICBzdGQ6OmNvdXQgPDwgZHVyYXRpb25fY2FzdDxtaWxsaXNlY29uZHM+KGhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCkgLSBzKS5jb3VudCgpIAogICAgICAgICAgICA8PCAibXMgd2l0aCAiIDw8IEE6Om5Td2FwcyA8PCAiIHN3YXBzXG4iOwogICAgfQo=