HDU ACM 4473 Exam->数论(思维-有关问题转换)

HDU ACM 4473 Exam->数论(思维-问题转换)

题意: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;
}