x 、y、n都是正整数,并且 显然,x >= n , y >= n ,现在假设 y = n +k (k为正整数) ,那么带入公式,可以得出 x = (n*(n+k))/k = n*n/k + n; 由于x 是正整数,现在的关键问题就是要求出 n*n/ k 有多少组正整数的可能,显然,所要求的就是 n*n 因子的个数// 问题已经非常接近答案了,但是最后还有一个问题,n<= 10^9 , 那么n*n <= 10^18 ,对于一个这么大的数字怎样才能求出它因子的个数呢?
命题1: 一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的个数就是,(r1+1)*(r2+1)*...*(rk+1).
如果一个数字 n = p1^r1 * p2^r2 * ... pk^rk ,那么 n*n = p1^r1 * p2^r2 * ... pk^rk * p1^r1 * p2^r2 * ... pk^rk ,它的因子的个数就是 (2*r1+1)*(2*r2+1)*...*(2*rk+1).
由1/x+1/y=1/n
简化成(x-n)(y-n)=n*n,
很明显,只要能将n*n进行因数分解,
则其解都满足题意。
假设n可写成:
a1^k1 * a2^k2 * a3^k3 * ... * am^km, (1)
其中a1,a2,a3,...am互质,
则n*n的约数为
(2k1+1)(2k2+1)(2k3+1)...(2km+1), (2)
记其积为O,
从而其存在的解的个数为
[O+1]/2,
#include<stdio.h>
#include<stdlib.h>
int prime( int num[] )//素数筛选
{
int hash[20000]={0};
for( int i=3; i<=200; i+=2 )
{
if( hash[i/2] )
continue;
int x=i<<1;
for( int j=i*i; j<40000; j+=x )
hash[j/2]=1;
}
int count=0;
num[++count]=2;
for( int i=1; i<20000; i++ )
{
if( hash[i]==0 )
num[++count]=(i<<1)+1;
}
return count;
}
int res( int num[], int count ,int number )
{
int sum=1;
for( int i=1; i<=count; i++ )
{
if( number==1 ) break;
int x=0;
while( number%num[i]==0 )
{
x++;
number/=num[i];
}
sum*=(2*x+1);
}
if( number!=1 )
sum*=3;
return sum;
}
int main()
{
int n,num[5000],number;
int count=prime( num );
scanf( "%d",&n );
for( int i=1; i<=n; i++ )
{
scanf( "%d",&number );
printf( "Scenario #%d:\n" ,i);
printf( "%d\n",(res( num,count,number )+1)/2 );
puts("");
}
return 0;
}