尝 试 着 写 出 前 几 位 的 二 进 制 来 尝试着写出前几位的二进制来 尝试着写出前几位的二进制来
0000
0000
0000
0001
0001
0001
0010
0010
0010
0011
0011
0011
0100
0100
0100
0101
0101
0101
0110
0110
0110
0111
0111
0111
1000
1000
1000
可 以 发 现 第 一 位 二 进 制 一 直 是 01 变 化 , 所 以 第 一 位 的 贡 献 是 n ( 第 一 位 二 进 制 是 最 后 一 列 ) 可以发现第一位二进制一直是01变化,所以第一位的贡献是n(第一位二进制是最后一列) 可以发现第一位二进制一直是01变化,所以第一位的贡献是n(第一位二进制是最后一列)
二 进 制 第 二 位 逢 2 进 1 , 所 以 只 有 进 1 的 时 候 和 前 面 的 0 不 同 , 贡 献 就 是 n / 2 二进制第二位逢2进1,所以只有进1的时候和前面的0不同,贡献就是n/2 二进制第二位逢2进1,所以只有进1的时候和前面的0不同,贡献就是n/2
所 以 推 到 二 进 制 第 i 位 , 贡 献 是 n < < ( i − 1 ) 所以推到二进制第i位,贡献是n<<(i-1) 所以推到二进制第i位,贡献是n<<(i−1)
累 加 即 可 累加即可 累加即可
#include <bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
typedef long long ll;
const int maxn=2e5+10;
ll n;
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
ll now=n,i=1,ans=0;
while(now)
{
ans+=n/i;
i*=2;
now>>=1;//看下一位二进制
}
cout<<ans<<endl;
}
}