分析: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 ", ans); return 0; }