题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4473
本文转自:http://www.cnblogs.com/hundundm/archive/2012/11/17/2775191.html
题目意思:
定义f(x) = 满足(a * b)|x的有序对(a,b)的个数。
然后输入一个n,求f(1) + f(2) + ... + f(n)
废话不多说,此题的关键在于:
把原题的条件(a * b)|x 转化为 a * b * y = x
然后就很好计算了,就是,输入一个n,计算有多少有序对(a, b ,y)满足a*b*y<=n
不妨设a<=b<=y
则,a<=n^(1/3) , b<=sqrt(n/a)
那么
对于三个数字都相同的情况,只计算一次: i i i
对于三个数字中有两个相同的情况,计算3次: i i j, i j i, j i i
对于均不相同的情况,计算6次: a b y ,a y b ,b a y ,b y a, y a b ,y b a
代码贴自己的:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define LL long long
LL pow2(LL n)
{
LL m = pow(n,0.5);
while(m*m<n) m++;
while(m*m>n) m--;
return m;
}
LL pow3(LL n)
{
LL m = pow(n,1.0/3);
while(m*m*m<n)m++;
while(m*m*m>n)m--;
return m;
}
int main()
{
LL n;
int ca = 1;
while(~scanf("%I64d",&n))
{
LL ans = 0;
LL m = pow3(n);
ans = m;
for(int i=1;i<=m;i++)
{
LL ni = n/i;
LL k = pow2(ni);
ans += (ni/i-i+k-i)*3;
for(int j=i+1;j<=k;j++)
{
ans += (ni/j-j)*6;
}
}
printf("Case %d: %I64d\n",ca++,ans);
}
return 0;
}