Johnny and Another Rating Drop( Codeforces Round #647 )

 

题目链接: 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;
}

 

posted @ 2020-06-05 15:57  blowhail  阅读(257)  评论(0编辑  收藏  举报
Live2D