一月17日新生冬季练习赛解题报告B.函数问题

B题的解题报告非常值得写,其解题思路让人叹为观止,比赛的时候没有一个人ac,其实我想用纯暴力劫一下试试呢,幸好没试,不然会挂的很惨

题目是这样的:

B.函数问题
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 12 (5 users) Total Accepted: 0 (0 users) Special Judge: No
Description

定义一个函数f(x),意思为x%(a*b)==0的a,b对数...如

f(1)=1:1*1

f(2)=3:1*1,1*2,2*1

f(3)=3:1*1,1*3,3*1

f(4)=6:1*1,1*2,2*1,2*2,1*4,4*1

.................

现在输入一个正整数N(N<=10^11)..问f(1)+f(2)+f(3)+f(4)+....f(N)的值...

Input

多组输入数据。 

 

每组数据输入一个n。

 

Output

每组数据输出问题结果,格式为Case #: ans。

Sample Input
1
3
6
10
15
21
28
Sample Output
Case 1: 1
Case 2: 7
Case 3: 25
Case 4: 53
Case 5: 95
Case 6: 161
Case 7: 246

这种题呢,看上去是求每个子问题,然后求和,做的过程你会发现单个子问题是没法全部求出来的,就算求出来也没有数组能够存的下(10^11)  就算存的下光是最后的遍历也会把时间全都用完  所以我们要整体的考虑 f(1)加到f(n)的和  

那么怎么整体考虑呢?

我们看一下给的前三组例子:

f(1)=1:1*1

f(2)=3:1*1,1*2,2*1

f(3)=3:1*1,1*3,3*1

求的是  f(1)+f(2)+f(3)

 

对于1 有(1,1) 1/(1*1)=1
对于2 有(1,1) (1,2) (2,1) 2/(1*1)=2 2/(1*2)=1 2/(2*1)=1
对于3 有(1,1) (1,3) (3,1) 3/(1*1)=3 3/(1*3)=1 3/(3*1)=1

 

我们把每两个相乘的数 左边的看做a 右边的看做 b   把相除的结果看做 c  

把所有分母都移到右边;

接下来这一步有些跳跃,需要自己想明白

 

那么:f(1)+f(2)+f(3)的问题就可以转换成a*b*c<=3的所有abc的种数

 

应用到所有就是  a*b*c<=n的所有abc的组合数  其中abc科翔等或者不等

 

 

接下来的问题就是求多少组了:

可以分为a b c 都相等  、 a b c 中有两个相等和abc都不想等这三种情况  

下面我边写代码边解释:

 

#include<iostream>

#include<string.h>

using namespace std;

 

int main()

{

    long long int n,a,b,c;///数据太大所以要用long long

 

    std::ios::sync_with_stdio(false);///加速cin cout  也可以直接使用c语言的输入输出

 

    while(cin>>n)

    {

        long long int ans = 0;///用来记录总种类数  ans=answer

        

        for(a = 1; a*a*a <= n; a++)///abc都相等的情况

            ans++;

 

        for(a = 1; a*a <= n; a++)///abc中有两个相同  相同的用a表示  另一个用b表示

        {

            b=n/a/a;///b并不是指的实际的b值 而是b的取值范围是1-b换句话说就是b的种类数

 

            if(b >= a)

                ans += (b-1)*3;///因为ab一定是不相等的  所以 要从 1--b中减去 和a相等的那种情况

                ///至于乘3  因为 aab的组合数  为 3      

 

            else

                ans += b*3;///这种情况是  b的范围是  a之内  所以和a相等

        }

        

        ///地下是三者都不想等的情况  只要a1遍历到n  ba+1遍历到n  cb+1遍历到n   再乘以组合数6就可以了^_^

        for(a = 1; a*a <= n; a++)///abc都不相等的情况

        {

            for(b = a+1; a*b <= n; b++)

            {

                c=n/a/b;

                if(c>b)

                    ans+=(c-b)*6;///不用解释了吧

                else

                    break;

            }

        }

 

        cout<<ans<<endl;

    }

    return 0;

}

posted @ 2014-01-18 16:55  悠悠我心。  阅读(471)  评论(0编辑  收藏  举报