This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/utility/bit/popcount.hpp"
usize popcount(u64 n)
n
を二進表記したときの1の数を返す。
C++20 以降では std::popcount(T n)
を使用すること。
基本方針として、「 $2^i$ bit ごとに区切り、それぞれの区間ごとにいくつ立っている bit があったか」を計算している。
#pragma once
#include "src/cpp-template/header/int-alias.hpp"
#include "src/cpp-template/header/size-alias.hpp"
#include <cassert>
namespace luz {
usize popcount(u64 x) {
assert(__cplusplus <= 201703L);
#ifdef __GNUC__
return __builtin_popcountll(x);
#endif
x -= (x >> 1) & 0x5555555555555555;
x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
x += (x >> 4) & 0x0f0f0f0f0f0f0f0f;
return x * 0x0101010101010101 >> 56 & 0x7f;
}
} // namespace luz
#line 2 "src/utility/bit/popcount.hpp"
#line 2 "src/cpp-template/header/int-alias.hpp"
#include <cstdint>
namespace luz {
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using u128 = __uint128_t;
} // namespace luz
#line 2 "src/cpp-template/header/size-alias.hpp"
#include <cstddef>
namespace luz {
using isize = std::ptrdiff_t;
using usize = std::size_t;
} // namespace luz
#line 5 "src/utility/bit/popcount.hpp"
#include <cassert>
namespace luz {
usize popcount(u64 x) {
assert(__cplusplus <= 201703L);
#ifdef __GNUC__
return __builtin_popcountll(x);
#endif
x -= (x >> 1) & 0x5555555555555555;
x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
x += (x >> 4) & 0x0f0f0f0f0f0f0f0f;
return x * 0x0101010101010101 >> 56 & 0x7f;
}
} // namespace luz