1. 程式人生 > >2013 ACM-ICPC南京全國邀請賽

2013 ACM-ICPC南京全國邀請賽

Count The Carries

One day, Implus gets interested in binary addition and binary carry. He will transfer all decimal digits to binary digits to make the addition. Not as clever as Gauss, to make the addition from a to b, he will add them one by one from a to b in order. For example, from 1 to 3 (decimal digit), he will firstly calculate 01 (1)+10 (2), get 11,then calculate 11+11 (3),lastly 110 (binary digit), we can find that in the total process, only 2 binary carries happen. He wants to find out that quickly. Given a and b in decimal, we transfer into binary digits and use Implus's addition algorithm, how many carries are there?


Input
Two integers a, b(0<=a<=b<1000000000), about 100000 cases, end with EOF.


Output
One answer per line.


Sample Input
1 2
1 3
1 4
1 6


Sample Output
0
2
3
6

題意:給出a b,把a--b中的所有數轉成二進位制,然後相加,求相加過程中有幾次低位向高位進位
剛開始直接把所有數進行二進位制轉化,這想想肯定超時,後面推規律發現只要求的所有二進位制相加後每一位的數進行處理即可以得到結果,但是求每一位上的1我還是用了轉二進位制的方法。。還是超時了。。換思路,轉二進位制肯定不行 要求幾個數的二進位制相加後每一位上的數值,列出幾個數即可以發現規律     00     01     10     11   100   101   110   111 1000 1001 1010 1011 1100 1101 1110 1111 可以發現 :0位上每隔2數就有1個1                    1位上每隔4數就有2個1                    2位上每隔8數就有4個1
                   3位上每隔16數就有8個1

所以只要求每一位上1的個數之和,後面在處理就行 程式碼:
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int M=1e5+5;
const int mod=1e9+7;
int num1[70];
int num2[70];
void cal(int a[],int n)//0-n每個數位上1的和
{
	int i,temp;
	temp=1;
	n++;
	for(i=0;i<64;i++)
	{
		if(temp>n)break;
		temp*=2;
		a[i]+=(n/temp)*(temp/2);
		if(n%temp>temp/2)//餘數大於temp/2,後面還有n%temp-temp個1
		  a[i]+=n%temp-temp/2;//或者a[i]+=n%(tmp/2);
	}
}
int main()
{
    int a,b,i;
    long long sum;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        memset(num1,0,sizeof(num1));
        memset(num2,0,sizeof(num2));
        cal(num1,a-1);
        cal(num2,b);
        for(i=0;i<64;i++)
        num2[i]-=num1[i];
        sum=0;
        for(i=0;i<63;i++)
        {
            sum+=num2[i]/2;
            num2[i+1]+=num2[i]/2;
        }
        printf("%lld\n",sum);
    }
    return 0;
}