题目链接: https://codeforces.com/contest/1362/problem/C
题目大意:计算从1-n 中,每相邻两个数的二进制的不同的数量差的和,比如100和101,有一个位置的数不同,那么他们的差值就为1,101和110,有两个位置不同,那么差值就为2.
思路: 如图,可以发现,算出来0到8的差值和异或之后的值,然后可以把他们放到树状数组里,正好符合树状数组的计算。(这里相邻两个二进制数的差值相当于 A[i] 异或的值相当于 C[i] )
明白可以用树状数组之后,就可以写代码了
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f #define mod 1000000007 using namespace std; ll lowbit(ll i) { return i&-i; } ll getsum(ll i) { ll sum=0; while(i>0) { sum+=i^(i-1); //这里i^(i-1) 就相当于树状数组的 c[i] i-=lowbit(i); } return sum; } int main () { ll n,i,t,j,k,p=1; cin>>n; ll m; while(n--) { cin>>m; k=getsum(m); cout<<k<<endl; } return 0; }