#pragma GCC optimize("O2")
#include <bits/stdc++.h>
template<int n, typename T>
inline int lowerBoundImpl(const T* __restrict arr, const T val) {
if (n == 1) { return val > arr[0]; }
else {
constexpr int mid = n / 2;
if (val > arr[mid]) { return mid+lowerBoundImpl<n-mid, T>(arr+mid, val); }
else { return lowerBoundImpl<mid, T>(arr,val); }
}
};
template<int n, typename T>
[[noinline]] int lowerBound(const T* __restrict arr, const T val) {
return lowerBoundImpl<n>(arr, val);
}
template<int n, typename T>
[[noinline]] int loserBound(const T* __restrict arr, const T val) {
return int(std::lower_bound(arr,arr+n,val)-arr);
}
std::vector<int> queries(1 << 9);
static int arr[1 << 20];
template<class T>
void test(const char* s, T f) {
std::cout << s << std::endl;
int res = 0;
double tin = (double)clock(), tout;
for (int i = 0; i < (1 << 15); i++) {
for (int q : queries) {
res += f(&arr[0], q);
}
}
tout = (double)clock();
std::cout << "time = " << (tout - tin) / CLOCKS_PER_SEC << "s, sum = " << res << std::endl;
}
int main() {
for (int i = 0; i < (1 << 20); i++) { arr[i] = i; }
std::mt19937 gen;
std::uniform_int_distribution<int> dist(0, 1 << 20);
for (auto &it : queries) { it = dist(gen); }
test("Testing std::lower_bound...", loserBound<1 << 20, int>);
test("Testing lowerBound...", lowerBound<1 << 20, int>);
return 0;
}
I3ByYWdtYSBHQ0Mgb3B0aW1pemUoIk8yIikKI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnRlbXBsYXRlPGludCBuLCB0eXBlbmFtZSBUPgppbmxpbmUgaW50IGxvd2VyQm91bmRJbXBsKGNvbnN0IFQqIF9fcmVzdHJpY3QgYXJyLCBjb25zdCBUIHZhbCkgewoJaWYgKG4gPT0gMSkgeyByZXR1cm4gdmFsID4gYXJyWzBdOyB9IAoJZWxzZSB7CgkJY29uc3RleHByIGludCBtaWQgPSBuIC8gMjsKCQlpZiAodmFsID4gYXJyW21pZF0pIHsgcmV0dXJuIG1pZCtsb3dlckJvdW5kSW1wbDxuLW1pZCwgVD4oYXJyK21pZCwgdmFsKTsgfQoJCWVsc2UgeyByZXR1cm4gbG93ZXJCb3VuZEltcGw8bWlkLCBUPihhcnIsdmFsKTsgfQoJfQp9OwoKdGVtcGxhdGU8aW50IG4sIHR5cGVuYW1lIFQ+Cltbbm9pbmxpbmVdXSBpbnQgbG93ZXJCb3VuZChjb25zdCBUKiBfX3Jlc3RyaWN0IGFyciwgY29uc3QgVCB2YWwpIHsKICAgIHJldHVybiBsb3dlckJvdW5kSW1wbDxuPihhcnIsIHZhbCk7Cn0KIAogCnRlbXBsYXRlPGludCBuLCB0eXBlbmFtZSBUPgpbW25vaW5saW5lXV0gaW50IGxvc2VyQm91bmQoY29uc3QgVCogX19yZXN0cmljdCBhcnIsIGNvbnN0IFQgdmFsKSB7CiAgICByZXR1cm4gaW50KHN0ZDo6bG93ZXJfYm91bmQoYXJyLGFycituLHZhbCktYXJyKTsKfQoKc3RkOjp2ZWN0b3I8aW50PiBxdWVyaWVzKDEgPDwgOSk7CnN0YXRpYyBpbnQgYXJyWzEgPDwgMjBdOwp0ZW1wbGF0ZTxjbGFzcyBUPgp2b2lkIHRlc3QoY29uc3QgY2hhciogcywgVCBmKSB7CiAgICBzdGQ6OmNvdXQgPDwgcyA8PCBzdGQ6OmVuZGw7CiAgICBpbnQgcmVzID0gMDsKICAgIGRvdWJsZSB0aW4gPSAoZG91YmxlKWNsb2NrKCksIHRvdXQ7CiAgICBmb3IgKGludCBpID0gMDsgaSA8ICgxIDw8IDE1KTsgaSsrKSB7CiAgICAgICAgZm9yIChpbnQgcSA6IHF1ZXJpZXMpIHsKICAgICAgICAgICAgcmVzICs9IGYoJmFyclswXSwgcSk7CiAgICAgICAgfQogICAgfQogICAgdG91dCA9IChkb3VibGUpY2xvY2soKTsKICAgIHN0ZDo6Y291dCA8PCAidGltZSA9ICIgPDwgKHRvdXQgLSB0aW4pIC8gQ0xPQ0tTX1BFUl9TRUMgPDwgInMsIHN1bSA9ICIgPDwgcmVzIDw8IHN0ZDo6ZW5kbDsKfQogCmludCBtYWluKCkgewoJZm9yIChpbnQgaSA9IDA7IGkgPCAoMSA8PCAyMCk7IGkrKykgeyBhcnJbaV0gPSBpOyB9CglzdGQ6Om10MTk5MzcgZ2VuOwoJc3RkOjp1bmlmb3JtX2ludF9kaXN0cmlidXRpb248aW50PiBkaXN0KDAsIDEgPDwgMjApOwoJZm9yIChhdXRvICZpdCA6IHF1ZXJpZXMpIHsgaXQgPSBkaXN0KGdlbik7IH0KCXRlc3QoIlRlc3Rpbmcgc3RkOjpsb3dlcl9ib3VuZC4uLiIsIGxvc2VyQm91bmQ8MSA8PCAyMCwgaW50Pik7Cgl0ZXN0KCJUZXN0aW5nIGxvd2VyQm91bmQuLi4iLCBsb3dlckJvdW5kPDEgPDwgMjAsIGludD4pOwoJcmV0dXJuIDA7Cn0=