52 lines
1.0 KiB
C++
52 lines
1.0 KiB
C++
#include "int_utils.h"
|
|
|
|
#if (defined(__GNUC__) && defined(__BMI2__))
|
|
#include <x86intrin.h>
|
|
#include <bmi2intrin.h> // _pdep_u32
|
|
#endif
|
|
|
|
int ilog2(uint64_t x) {
|
|
int log = 0;
|
|
while (x >>= 1) {
|
|
log++;
|
|
}
|
|
return log;
|
|
}
|
|
|
|
uint64_t isqrt(uint64_t x) {
|
|
// implements a binary search
|
|
uint64_t root = 0;
|
|
uint64_t left = 0; // left boundary
|
|
uint64_t right = x + 1; // right boundary
|
|
|
|
while(left + 1UL < right) {
|
|
root = (left + right) / 2UL;
|
|
if (root * root <= x) {
|
|
left = root;
|
|
} else {
|
|
right = root;
|
|
}
|
|
}
|
|
return left;
|
|
}
|
|
|
|
uint32_t invTriag(uint32_t x) {
|
|
uint64_t root = isqrt(8UL * static_cast<uint64_t>(x) + 1UL);
|
|
if (root * root != 8UL * x + 1UL) {
|
|
return 0;
|
|
}
|
|
return (root - 1) / 2;
|
|
}
|
|
|
|
uint64_t nrSubSets(uint64_t n, uint64_t k) {
|
|
uint64_t sum = 1, binom = 1;
|
|
|
|
for (uint64_t i = 1; i <= k; ++i) {
|
|
binom *= n--;
|
|
binom /= i;
|
|
sum += binom;
|
|
}
|
|
|
|
return sum;
|
|
}
|