题意:f(x) = 满足(a * b)|x(x%(a*b)==0)的有序对(a,b)的个数,输入n,求f(1) + f(2) + ... + f(n)。
分析:对于任意一个a*b|c可以视为a*b*c = x,那么就可以把问题转化为a*b*c <= x的解的组合的个数问题了。
设a<=b<=c,则a<=n^(1/3) , b<=sqrt(n/a),那么分为三种情况:
1、对于三个数字都相同的情况,只计算一次: i i i
2、对于三个数字中有两个相同的情况,计算3次: i i j, i j i, j i i
3、对于均不相同的情况,计算6次: a b c ,a c b ,b a c ,b c a, c a b ,c b a。
#include<iostream> using namespace std; int main() { __int64 n,i,j,k,ans; int t=0; while(scanf("%I64d",&n)==1) { ans=0; for(i=1;i*i*i<=n;i++) ans++; //三个相等的情况 for(i=1;i*i<=n;i++) //只有两个相等的情况 { k=n/i/i; if(k>=i) ans+=(k-1)*3; //减去3个相等的 else ans+=k*3; } for(i=1;i*i*i<=n;i++) for(j=i+1;j<=n;j++) //三个均不相等的情况 { k=n/i/j; if(k>j) ans+=(k-j)*6; else break; } printf("Case %d: %I64d\n",++t,ans); } return 0; }
HDU ACM 4473 Exam->数论(思维-问题转换)
原文地址:http://blog.csdn.net/a809146548/article/details/46426663