题目: 题目链接
描述:
问一个数n可以被2的1到m次方表示的最小代价,使用一次2^k就带来1的代价。
n、m的范围都是1e9。
题解:
使用__builtin_popcount
函数统计n中有多少个1(二进制),可以知道m不超过30。由于超过m的部分没法一次表示,所以减去,再加上n / 2^m即可。
代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define fi first
#define se second
#define MP(A, B) make_pair(A, B)
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL LINF = 0x3f3f3f3f3f3f3f3fLL;
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int maxn = 1e3 + 5;
const int dx[] = {-1, 0, 1, 0, -1, -1, 1, 1};
const int dy[] = {0, 1, 0, -1, 1, -1, 1, -1};
template<class T> inline void mem(T &A, int x) { memset(A, x, sizeof(A)); }
template<class T0, class T1> inline void mem(T0 &A0, T1 &A1, int x) { mem(A0, x), mem(A1, x); }
template<class T0, class T1, class T2> inline void mem(T0 &A0, T1 &A1, T2 &A2, int x) { mem(A0, x), mem(A1, x), mem(A2, x); }
template<class T0, class T1, class T2, class T3> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x); }
template<class T0, class T1, class T2, class T3, class T4> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x), mem(A4, x); }
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x), mem(A4, x), mem(A5, x); }
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x), mem(A4, x), mem(A5, x), mem(A6, x); }
template<class T> inline T min(T a, T b, T c) { return min(min(a, b), c); }
template<class T> inline T max(T a, T b, T c) { return max(max(a, b), c); }
template<class T> inline T min(T a, T b, T c, T d) { return min(min(a, b), min(c, d)); }
template<class T> inline T max(T a, T b, T c, T d) { return max(max(a, b), max(c, d)); }
template<class T> inline T min(T a, T b, T c, T d, T e) { return min(min(min(a,b),min(c,d)),e); }
template<class T> inline T max(T a, T b, T c, T d, T e) { return max(max(max(a,b),max(c,d)),e); }
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int T, n, m;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
m = min(30, m);
printf("%d\n", __builtin_popcount(n) - __builtin_popcount(n >> m) + (n >> m));
}
return 0;
}