UVA_12670_Counting ones(统计区间二进制1个数)

来源:互联网 发布:网络借贷需要什么资料 编辑:程序博客网 时间:2024/06/05 17:37

题目链接:http://uva.onlinejudge.org/external/126/12670.pdf


题型:数论


题意:求从a到b之间的所有数的二进制数中的1的个数。


分析:

二进制数按顺序可以发现,二进制中分布都是规律的,最低位是010101...,次低位是00110011...

算出0到b之间的1的个数和0到a-1之间的1的个数,然后差值就是a到b之间的1的个数。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cstring>#define LL long longusing namespace std;LL cal(LL x){    LL cnt = 0;    LL tmp = x;    while(tmp){        tmp /= 2;        cnt ++;    }    LL mul = 1;    LL ans = 0;    for(int i=1;i<=cnt;i++){        //cout<<"mul = "<<mul<<endl;        LL ts = (x+1)/(mul*2)*mul;        LL yu = (x+1)%(mul*2);        yu = (yu<=mul)? 0 : (yu-mul);        ans += (ts + yu);        mul*=2;    }    return ans;}int main(){    LL a,b;    while(~scanf("%lld%lld",&a,&b)){        //printf("%lld\n",cal(a-1));        //printf("%lld\n",cal(b));        printf("%lld\n",cal(b)-cal(a-1));    }    return 0;}/*1000000000000000 100000000000000002 129007199254740992 9007199254740992*/

0 0