hdu 4588Count The Carries(循环节 规律题目)

Count The Carries

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 508    Accepted Submission(s): 184


Problem Description
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
 

Source
2013 ACM-ICPC南京赛区全国邀请赛——题目重现
 


题目大意:从a一直加到b,a+(a+1)+....+(b-1)+b.问你中间出现了多少次进位。

解题思路:这个题目WZY在几分钟的时候就读懂了,当时没有什么想法,只知道暴力不可以,后来过了另外的两个题目,才开始认真思考这个。。 其实早该想到一步处理的,WZY提出全部一起加,然后有循环节,但是他的想法分类过于麻烦,再加上没有听懂他往下找的下界,所以一直在想从上面找,可以简化成算每一位从(0-b)的1个数减去(0-(a-1))的1个数,然后再加上低位给高位的进位。循环节很容易找到,为2^i.后来就是统计,A的时候出现各种bug..

1.处理到tb为0之后,还要看是否还能往前继续进位。具体见代码。
2.记住用long long....

题目地址:Count The Carries

AC代码:
#include<iostream>
using namespace std;

long long cal(int a,int b)
{
    int t=2,tt=1,tb=b;
    long long ans=0;
    int p,tmp;
    int s1,s2,s;
    s=0;
    //算的时候把0当成第一个数
    while(tb)
    {
        p=a/t;   //0到a-1有多少个周期
        tmp=a%t;
        s1=p*tt;
        if(tmp>tt)
            s1+=tmp-tt;
        p=(b+1)/t;   //0到b有多少个周期
        tmp=(b+1)%t;
        s2=p*tt;
        if(tmp>tt)
            s2+=tmp-tt;
        ans+=(s2-s1+s)>>1;
        s=(s+s2-s1)>>1;  //给下一位的进位
        tb>>=1;
        t<<=1,tt<<=1;
        //cout<<s<<' '<<ans<<endl;
    }

    while(s)  //重要!!
    {
        s>>=1;
        ans+=s;
    }
    return ans;
}

int main()
{
    int a,b;
    while(cin>>a>>b)
        cout<<cal(a,b)<<endl;
    return 0;
}




你可能感兴趣的:(2013邀请赛)