Hdu 4588 Count The Carries (规律)

来源:互联网 发布:广西老年大学网络报名 编辑:程序博客网 时间:2024/06/06 09:29

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4588

思路:

0     0000

1     0001

2     0010

3     0011

4     0100

5     0101

6     0110

7     0111

8    1000

9    1001

10  1010

观察可知,第i位有(1<<i)个0,与(1<<i)个1,按照长度为(1<<(i+1))长度循环。则对于数n,可以求出1到n中各位1的个数num2[i],则进位次数为sum(num[i] / 2),注意每次向高位进位(num2[i+1]+=num2[i] / 2)。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;LL num1[65],num2[65];void solve(LL num[],LL n){    for(int i=0;i<63;i++) num[i]=0;    n++;    for(int i=0;i<63;i++)    {       LL tmp1=(1LL)<<(i+1);       LL tmp2=(1LL)<<i;       num[i]+=n/tmp1*(1<<i);       if(n%tmp1>tmp2)num[i]+=n%tmp1-tmp2;    }    /*for(int i=0;i<63;i++)        cout<<i<<" "<<num[i]<<endl;*/}int main(){    LL a,b;    //solve(num1,20);    //solve(num2,6);    while(scanf("%I64d%I64d",&a,&b)==2)    {        solve(num1,a-1);        solve(num2,b);        for(int i=0;i<63;i++) num2[i]-=num1[i];        LL ans=0;        for(int i=0;i<63;i++)        {            ans+=num2[i]/2;            num2[i+1]+=num2[i]/2;        }        printf("%I64d\n",ans);    }    return 0;}



0 0
原创粉丝点击