C. Johnny and Another Rating Drop
问题:给出一个数n,求从0到n相邻两个数二进制不同位数的总和。
例如 1 = ( 01 ) 2 , 2 = ( 10 ) 2 1=(01)_2,2=(10)_2 1=(01)2,2=(10)2不同位数就为2。
我们列举一下找找规律:
0 = 0000 0=0000 0=0000
1 = 0001 1=0001 1=0001
2 = 0010 2=0010 2=0010
3 = 0011 3=0011 3=0011
4 = 0100 4=0100 4=0100
5 = 0101 5=0101 5=0101
6 = 0110 6=0110 6=0110
7 = 0111 7=0111 7=0111
数字每加1次,最低位改变,每加2次,次低位改变,每加4次,倒数第三位改变……
我们对n每次除2,求各个位数改变次数,求得最终答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll come(ll x) {
ll ans = 0;
while(x) {
ans += x;
x >>= 1;//每次除2
}
return ans;
}
int main() {
ll t, n;
scanf("%lld", &t);
while(t--) {
scanf("%lld", &n);
printf("%lld", come(n));
}
return 0;
}