#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; //Integer-Related typedef long long i64; typedef unsigned long long ui64; //vector-Related template using vv = vector>; template using vvv = vector>>; typedef vector vi64; typedef vector vbool; typedef vv vvi64; typedef vv vvbool; typedef vvv vvvi64; typedef vvv vvvbool; typedef pair pi64; typedef vector vstr; //これで最大値優先 template> using prque = priority_queue, Pred>; //set-Related #include typedef set si64; typedef multiset msi64; typedef unordered_set usi64; //Calculation-Related inline i64 rm(const i64 l, const i64 r) { i64 val = l % r; if (val >= 0) { return val; } else { return val + r; } } template T r_accumulate(const vector& vec) { return std::accumulate(vec.begin(), vec.end(), T{}); } template void r_insert(vector& to, vector& from) { ranges::copy(from, back_inserter(to)); } constexpr std::string repeater3030(const std::string& s, int number) { std::string cur = ""; for (i64 i = 0; i < number; i++) { cur += s; } return cur; } constexpr std::string repeater3030(const char& c, int number) { string s(1, c); return repeater3030(s, number); } constexpr i64 pow_i64(i64 base, i64 exp) { i64 res = 1LL; while (exp > 0LL) { if (exp & 1) { res *= base; } exp >>= 1LL; base *= base; } return res; } template T eqmin(T& a, T b) { a = min(a, b); return a; } template T eqmax(T& a, T b) { a = max(a, b); return a; } //Output-Related template std::ostream& operator<<(std::ostream& os, const std::pair& p) { os << "(" << p.first << ", " << p.second << ")"; return os; } template inline void output(const T elem) { std::cout << elem << std::endl; } #ifndef __INTELLISENSE__ template inline void output(const pair elem) { std::cout << "(" << elem.first << "," << elem.second << ")" << std::endl; } template inline void output(const vector& vec) { for (T elem : vec) { std::cout << elem << " "; } std::cout << std::endl; } template inline void output(const vector>& vvec) { for (vector vec : vvec) { std::cout << "("; for (T elem : vec) { std::cout << elem << " "; } std::cout << ")"; } std::cout << std::endl; } template inline void output(const vector>>& vvvec) { for (vector> vvec : vvvec) { std::cout << "["; for (vector vec : vvec) { std::cout << "("; for (T elem : vec) { std::cout << elem << " "; } std::cout << ")"; } std::cout << "]" << std::endl; } } #endif template inline void output_iter(const T& iter) { for (auto&& elem : iter) { std::cout << elem << " "; } std::cout << std::endl; } /** * ACLibrary-fewnwicktree * Ref : https://atcoder.github.io/ac-library/master/document_ja/ */ /** * ACLibrary-internaltypetraits * Ref : https://atcoder.github.io/ac-library/master/document_ja/ */ #include namespace atcoder { namespace internal { #ifndef _MSC_VER template using is_signed_int128 = typename std::conditional::value || std::is_same::value, std::true_type, std::false_type>::type; template using is_unsigned_int128 = typename std::conditional::value || std::is_same::value, std::true_type, std::false_type>::type; template using make_unsigned_int128 = typename std::conditional::value, __uint128_t, unsigned __int128>; template using is_integral = typename std::conditional::value || is_signed_int128::value || is_unsigned_int128::value, std::true_type, std::false_type>::type; template using is_signed_int = typename std::conditional<(is_integral::value && std::is_signed::value) || is_signed_int128::value, std::true_type, std::false_type>::type; template using is_unsigned_int = typename std::conditional<(is_integral::value && std::is_unsigned::value) || is_unsigned_int128::value, std::true_type, std::false_type>::type; template using to_unsigned = typename std::conditional< is_signed_int128::value, make_unsigned_int128, typename std::conditional::value, std::make_unsigned, std::common_type>::type>::type; #else template using is_integral = typename std::is_integral; template using is_signed_int = typename std::conditional::value && std::is_signed::value, std::true_type, std::false_type>::type; template using is_unsigned_int = typename std::conditional::value && std::is_unsigned::value, std::true_type, std::false_type>::type; template using to_unsigned = typename std::conditional::value, std::make_unsigned, std::common_type>::type; #endif template using is_signed_int_t = std::enable_if_t::value>; template using is_unsigned_int_t = std::enable_if_t::value>; template using to_unsigned_t = typename to_unsigned::type; } // namespace internal } // namespace atcoder namespace atcoder { // Reference: https://en.wikipedia.org/wiki/Fenwick_tree template struct fenwick_tree { using U = internal::to_unsigned_t; public: fenwick_tree() : _n(0) {} explicit fenwick_tree(int n) : _n(n), data(n) {} void add(int p, T x) { assert(0 <= p && p < _n); p++; while (p <= _n) { data[p - 1] += U(x); p += p & -p; } } T sum(int l, int r) { assert(0 <= l && l <= r && r <= _n); return sum(r) - sum(l); } private: int _n; std::vector data; U sum(int r) { U s = 0; while (r > 0) { s += data[r - 1]; r -= r & -r; } return s; } }; } // namespace atcoder /** * ACLibrary-segtree * Ref : https://atcoder.github.io/ac-library/master/document_ja/ */ /** * ACLibrary-internalbit * Ref : https://atcoder.github.io/ac-library/master/document_ja/ */ #ifdef _MSC_VER #include #endif #if __cplusplus >= 202002L #endif namespace atcoder { namespace internal { #if __cplusplus >= 202002L using std::bit_ceil; #else // @return same with std::bit::bit_ceil unsigned int bit_ceil(unsigned int n) { unsigned int x = 1; while (x < (unsigned int)(n)) x *= 2; return x; } #endif // @param n `1 <= n` // @return same with std::bit::countr_zero int countr_zero(unsigned int n) { #ifdef _MSC_VER unsigned long index; _BitScanForward(&index, n); return index; #else return __builtin_ctz(n); #endif } // @param n `1 <= n` // @return same with std::bit::countr_zero constexpr int countr_zero_constexpr(unsigned int n) { int x = 0; while (!(n & (1 << x))) x++; return x; } } // namespace internal } // namespace atcoder namespace atcoder { #if __cplusplus >= 201703L template struct segtree { static_assert(std::is_convertible_v>, "op must work as S(S, S)"); static_assert(std::is_convertible_v>, "e must work as S()"); #else template struct segtree { #endif public: segtree() : segtree(0) {} explicit segtree(int n) : segtree(std::vector(n, e())) {} explicit segtree(const std::vector& v) : _n(int(v.size())) { size = (int)internal::bit_ceil((unsigned int)(_n)); log = internal::countr_zero((unsigned int)size); d = std::vector(2 * size, e()); for (int i = 0; i < _n; i++) d[size + i] = v[i]; for (int i = size - 1; i >= 1; i--) { update(i); } } void set(int p, S x) { assert(0 <= p && p < _n); p += size; d[p] = x; for (int i = 1; i <= log; i++) update(p >> i); } S get(int p) const { assert(0 <= p && p < _n); return d[p + size]; } S prod(int l, int r) const { assert(0 <= l && l <= r && r <= _n); S sml = e(), smr = e(); l += size; r += size; while (l < r) { if (l & 1) sml = op(sml, d[l++]); if (r & 1) smr = op(d[--r], smr); l >>= 1; r >>= 1; } return op(sml, smr); } S all_prod() const { return d[1]; } template int max_right(int l) const { return max_right(l, [](S x) { return f(x); }); } template int max_right(int l, F f) const { assert(0 <= l && l <= _n); assert(f(e())); if (l == _n) return _n; l += size; S sm = e(); do { while (l % 2 == 0) l >>= 1; if (!f(op(sm, d[l]))) { while (l < size) { l = (2 * l); if (f(op(sm, d[l]))) { sm = op(sm, d[l]); l++; } } return l - size; } sm = op(sm, d[l]); l++; } while ((l & -l) != l); return _n; } template int min_left(int r) const { return min_left(r, [](S x) { return f(x); }); } template int min_left(int r, F f) const { assert(0 <= r && r <= _n); assert(f(e())); if (r == 0) return 0; r += size; S sm = e(); do { r--; while (r > 1 && (r % 2)) r >>= 1; if (!f(op(d[r], sm))) { while (r < size) { r = (2 * r + 1); if (f(op(d[r], sm))) { sm = op(d[r], sm); r--; } } return r + 1 - size; } sm = op(d[r], sm); } while ((r & -r) != r); return 0; } private: int _n, size, log; std::vector d; void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); } }; } // namespace atcoder using namespace atcoder; /** * Graph一式 * Author : WhiteKnight */ struct Dest { i64 to; i64 cost; }; typedef vector> wgraphList;//Weighted,List typedef vector> sgraphList;//Simple,List typedef vector vedge; typedef vvi64 wgraphMat;//Weighted,Matrix wgraphList translate_simple_weight(sgraphList graph) { i64 N = graph.size(); wgraphList res(N); for (i64 i = 0; i < N; i++) { for (auto&& e : graph[i]) { res[i].push_back({e,1}); } } return res; } template wgraphList translate_mat_list(wgraphMat graph){ i64 N = graph.size(); wgraphList res(N); for (i64 i = 0; i < N; i++) { for (i64 j = 0; j < N; j++) { if(graph[i][j] >= INF){ continue; } res[i].push_back({ j,graph[i][j] }); } } return res; } #include #include #include using namespace boost; namespace mp = boost::multiprecision; typedef mp::int128_t i128; typedef mp::uint128_t ui128; typedef mp::cpp_dec_float_100 float100; typedef mp::cpp_dec_float_50 float50; using q64 = rational; /* * Point-Related(IntegerOnly) * Author : WhiteKnight * Submit:https://atcoder.jp/contests/abc421/tasks/abc421_d */ template struct Point { private: void single_rect_rotate(Point min_anchor, i64 size) { Point res = { y - min_anchor.y + min_anchor.x, size - 1 - (x - min_anchor.x) + min_anchor.y }; x = res.x; y = res.y; } public: T1 x, y; Point() : x(0), y(0) {} Point(T1 x_val, T1 y_val) : x(x_val), y(y_val) {} Point& operator+=(const Point& rhs) { x += rhs.x; y += rhs.y; return *this; } Point& operator-=(const Point& rhs) { x -= rhs.x; y -= rhs.y; return *this; } Point& operator*=(T1 scalar) { x *= scalar; y *= scalar; return *this; } Point& operator/=(T1 scalar) { x /= scalar; y /= scalar; return *this; } /** * @brief ベクトルの大きさを計算します。 * @return ベクトルの大きさ。 */ T2 magnitude() const { return std::sqrt(static_cast(x) * x + static_cast(y) * y); } /** * @brief ベクトルを五種類に大別して向きを表す。 * @return T1型の正規化されたベクトル。 */ Point direction() const { return Point(sign(x),sign(y)); } /** * @brief このベクトルを正規化した新しいベクトルを返します。 * @return T2型の正規化されたベクトル。 */ Point normalized() const { T2 mag = magnitude(); if (mag > 0) { return Point(x / mag, y / mag); } return Point(0.0, 0.0); } //included bool in(i64 min_x,i64 max_x,i64 min_y,i64 max_y) { return min_x <= x && x <= max_x && min_y <= y && y <= max_y; } //min_anchor : incl, clockwise void rect_rotate(Point min_anchor, i64 size, i64 cnt) { for (i64 i = 0; i < cnt % 4; i++) { single_rect_rotate(min_anchor, size); } } }; template inline Point operator+(Point lhs, const Point& rhs) { return lhs += rhs; } template inline Point operator-(Point lhs, const Point& rhs) { return lhs -= rhs; } template inline Point operator*(Point lhs, T1 scalar) { return lhs *= scalar; } template inline Point operator*(T1 scalar, Point rhs) { return rhs *= scalar; } template inline Point operator/(Point lhs, T1 scalar) { return lhs /= scalar; } template inline bool operator==(const Point& lhs, const Point& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } template inline bool operator!=(const Point& lhs, const Point& rhs) { return !(lhs == rhs); } /** * @brief 2点間のユークリッド距離(直線距離)を計算します。 * @param p1 始点 * @param p2 終点 * @return double型の距離 */ template inline T2 distance_euclidean(const Point& p1, const Point& p2) { T2 dx = static_cast(p1.x) - p2.x; T2 dy = static_cast(p1.y) - p2.y; return std::sqrt(dx * dx + dy * dy); } /** * @brief 2点間のマンハッタン距離を計算します。 * @param p1 始点 * @param p2 終点 * @return 座標と同じ型の距離 */ template inline T1 distance_manhattan(const Point& p1, const Point& p2) { return std::abs(p1.x - p2.x) + std::abs(p1.y - p2.y); } template std::ostream& operator<<(std::ostream& os, const Point& p) { os << "(" << p.x << ", " << p.y << ")"; return os; } using point = Point; /* * Submit : https://atcoder.jp/contests/abc297/tasks/abc297_c */ void replace(string& S, string from, string to) { assert(from.size() == to.size()); size_t start_pos = 0; while ((start_pos = S.find(from, start_pos)) != std::string::npos) { S.replace(start_pos, from.length(), to); start_pos += to.length(); } } vi64 get_digits(i64 val) { assert(val >= 0); if (val == 0) { return { 0 }; } vi64 res; while (val > 0) { res.push_back(val % 10); val /= 10; } return res; } //0-indexedで処理していたものから0部分をはねる template vv cut_false(vv& base) { vv res = base; res.erase(res.begin()); for (auto&& e : res) { e.erase(e.begin()); } return res; } std::array gridOn = { point(1,0),point(0,1),point(-1,0),point(0,-1) }; //Main Flow /* * Convert Base & Reverse Convert Base * Ref(一つ目) : https://ei1333.github.io/library/math/number-theory/convert-base.hpp * Submit : https://atcoder.jp/contests/abc414/tasks/abc414_c */ //i番目には下からi桁目(0-indexed) template vector convert_base(T x, T b) { vector ret; T t = 1, k = abs(b); while (x) { ret.emplace_back((x * t) % k); if (ret.back() < 0) ret.back() += k; x -= ret.back() * t; x /= k; t *= b / k; } if (ret.empty()) ret.emplace_back(0); return ret; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << setprecision(15); i64 N; cin >> N; auto digits = convert_base(N,2); bool over = ranges::count_if(digits,[](i64 val){ return val > 0; }) > 1; i64 res = digits.size() - 1 + over; output(res); return 0; }