ZOJ3629 Treasure Hunt IV(找规律,推公式)

Treasure Hunt IV Time Limit: 2 Seconds       Memory Limit: 65536 KB

Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled a from b in front of her.
Alice was very excited but unfortunately not all of the treasures are real, some are fake.
Now we know a treasure labled n is real if and only if [n/1] + [n/2] + ... + [n/k] + ... is even.
Now given 2 integers a and b, your job is to calculate how many real treasures are there.

Input

The input contains multiple cases, each case contains two integers a and b (0 <= a <= b <= 263-1) seperated by a single space. Proceed to the end of file.

Output

Output the total number of real treasure.

Sample Input

0 2
0 10

Sample Output

1
6
Author:  QU, Zhe
Contest:  ZOJ Monthly, July 2012


题目大意:给你一个区间,问你这个区间内的特殊数有多少,特殊数n的定义是n/1+n/2+n/3+....+n/n为偶数即可。

    解题思路:不要左想右想,直接打表看奇数偶数的特性,开始打了20,发现是1个0,3个1,5个0,7个1。。。。然后很喜悦,打了100表,发现真的是这个规律,就像哥伦布发现新大陆一样,于是开始默默地推公式。。。

发现不是很好推,我把这个结论告诉了yb,以为他有简单的方法解决一下,最后我还是自己拿了纸和笔到旁边推公式去了。

可以找规律,区间落点分别是1 2^2 3^2 4^2 5 ^2
1.直接开根号,看他们在哪个区间。
2.如果他们在一个区间,直接求和即可。
3.看他们落在奇数点还是偶数点,然后分情况讨论。
4.推0个数的求和个数公式。

好吧,我又坑了。
第一发wa是因为从0开始计数的,而我是从1开始计数的,所以a,b都要加1,再计算。然后还是wa了,就在看自己公式哪里推错了,,,,实际上是一个地方爆了long long,唉,做题不谨慎啊。。。。

题目地址:Treasure Hunt IV


AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;

int main()
{
    unsigned long long a,b;
    unsigned long long p1,p2;

    //printf("%lld\n",(1<<63)-1);


    unsigned long long ans,t1,t2;
    while(cin>>a>>b)
    {
        a++,b++;
        p1=sqrt(a+0.5);
        p2=sqrt(b+0.5);

        if(p1==p2)  //如果他们落到了同一个地方
        {
            if(p1&1)
            {
                if(p1*p1==a)
                    printf("1\n");
                else
                    printf("0\n");
            }
            else
            {
                if(p1*p1==a)
                    cout<<b-a<<endl;
                else
                    cout<<b-a+1<<endl;
            }
            continue;
        }
        
        ans=0;
        if(p1&1)  //ok
        {
            if(p1*p1==a)
              ans+=1;
            t1=p1+2;
        }
        else
        {
            if(p1*p1==a)
                t1=p1+1;
            else
            {
                ans+=(p1+1)*(p1+1)-a+1;  //就是这个地方爆的long long啊,巨坑。。
                t1=p1+3;
            }
        }

        if(p2&1)
        {
            t2=p2;
        }
        else
        {
            ans+=b-p2*p2;
            t2=p2-1;
        }

        t1=(t1+1)/2,t2=(t2+1)/2,t1--;

        //下面是用公式计算中间的0,个数为1,5,9,13,
        //通项为4n-3,求和公式为(2n-1)*n
        if(t2>=t1)
            ans=ans+(2*t2-1)*t2-(2*t1-1)*t1;

        cout<<ans<<endl;
    }
    return 0;
}

/*
0 11538571374624767
5769285672726615
123 321
87
*/




你可能感兴趣的:(规律)