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 }
2013 南京邀请赛 C count the carries
时间: 2024-10-12 20:19:29