noip模拟赛 a

分析:f(n)就是问有多少对a*b*c = n,如果是Σf(i),那就是问有多少对a*b*c <= n.

      这道题和之前做过的一道数三角形的题差不多:传送门,先假设一下a <= b <= c,=和<不好同时处理,那么我们就分开处理,先处理<的情况,a <= 三次根号下n,b * b <= n / a,然后c就可以利用范围统计出来了.因为这里强行规定了a < b < c,所以最后还要乘上3个数的排列数6.

      接下来处理有两个数相等的情况,枚举相等的那个数,还是根据另外一个数的范围来求方案数,所得答案乘上3个数中选2个相同的数的方案数就可以了,但是这样做有一个问题,就是可能会有a*a*a这种情况,不管选哪两个数就是同一种情况,我们在处理的时候要把这个答案给减掉,最后在来算3个数相同的情况.

      感觉钟长者出的这类数学题都有一个共同的特点:利用取值范围求方案数.一般的解法就是先规定一个大小关系,求出方案数后乘以排列数,然后去重.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

ll n, temp, ans;

int main()
{
    scanf("%lld", &n);
    for (ll a = 1; a * a <= (n / a); a++)
        for (ll b = a + 1; b * b <= (n / a); b++)
            temp += n / (a * b) - b;
    temp *= 6;
    ans += temp;
    temp = 0;
    for (ll a = 1; (a * a) <= n; a++)
    {
        temp += n / (a * a);
        if (a * a <= n / a)
            temp--;
    }
    temp *= 3;
    ans += temp;
    for (ll a = 1; a * a <= n / a; a++)
        ans++;
    printf("%lld\n", ans);
return 0;
}

 

posted @ 2017-10-17 22:09  zbtrs  阅读(172)  评论(0编辑  收藏  举报