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 }