2013 南京邀请赛 C count the carries

 1 /**
 2 大意: 给定区间(a,b), 将其转化为二进制 计算从a+(a+1)+(a+2)。。。。+(a+b-1),一共有多少次进位
 3 思路: 将(a,b)区间内的数,转化为二进制后,看其每一位一共有多少个1 
 4           可知最低位循环为2,第二位循环为4 
 5           ---〉 所以每一位的1的个数为 : 假设为第三位  (n-n%8)/8*8/2===>(n-n%8)/2
 6                    ------> 如果n%8 大于8/2 那么应该再加上 n%8-8/2
 7 **/
 8 #include <iostream>
 9 #include <cstring>
10 using namespace std;
11 
12 void cal(int num[],int n){
13     long long mod =1;
14     n++;
15     for(int i=0;i<64;i++){
16         if(mod>n)
17             break;
18         mod = mod*2;
19         num[i] += (n-n%mod)/2;
20         if(n%mod > mod/2) num[i] += n%mod-mod/2;
21     }
22 }
23 int main()
24 {
25     long long a,b;
26     int anum[100],bnum[100];
27     while(cin>>a>>b){
28         memset(anum,0,sizeof(anum));
29         memset(bnum,0,sizeof(bnum));
30         cal(anum,a-1);
31         cal(bnum,b);
32         for(int i=0;i<64;i++)
33             bnum[i]-=anum[i];
34         long long ans =  0;
35         for(int i=0;i<64;i++){
36             ans += bnum[i]/2;
37             bnum[i+1] += bnum[i]/2;
38         }
39         cout<<ans<<endl;
40     }
41     return 0;
42 }

 

posted @ 2014-05-12 21:05  夜晓楼  阅读(219)  评论(0编辑  收藏  举报