Diophantus of Alexandria
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1683 Accepted Submission(s): 633
Consider the following diophantine equation:
Diophantus is interested in the following question: for a given n, how many distinct solutions (i. e., solutions satisfying x ≤ y) does equation (1) have? For example, for n = 4, there are exactly three distinct solutions:
1 / 6 + 1 / 12 = 1 / 4
1 / 8 + 1 / 8 = 1 / 4
Clearly, enumerating these solutions can become tedious for bigger values of n. Can you help Diophantus compute the number of distinct solutions for big values of n quickly?
2 4 1260
Scenario #1: 3 Scenario #2: 113
满足 1 / x + 1 / y = 1 / n 的正整数解的对数。 1<= n <= 10^9 , 1<= x <= y
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).
这个问题就转化成了求 n <= 10^9 的素因子的问题,只需要先筛选出 sqrt(10^9) 内的素数,然后用n去试除 sqrt(n) 中的每一个即可,当然,n可能会有大于sqrt(n) 的因子呶//. 只试到 sqrt(n),怎么找出所有的素因子呢,不妨想一想,如果n有大于sqrt(n) 的素因子,它会有几个,又是多少呢? //(答案。此时除过剩下的n自己就是素数。。T-T。)
#include <iostream>
#include <cmath>
#include <cstring>
#define maxn 50000
bool prime[maxn];
int num[maxn];
int pn;
int ans;
int T;
int n ;
void Init()
{
int i,j;
int p;
memset(prime,true,sizeof(prime));
for(i=2;i<=maxn;i++)
for(j=2;i*j<maxn;j++)
prime[i*j] = false;
p = 0;
for(i=2;i<maxn;i++)
if(prime[i]) num[p++]= i;
pn = p;
}
int main()
{
int i,j,r,up;
Init();
scanf("%d",&T);
for(i=1;i<=T;i++)
{
scanf("%d",&n);
ans = 1;
for(j=0;j<pn;j++)
{
up = (int)sqrt(n*1.0)+1;
if(num[j]>up) break;
r = 0;
while(n%num[j]==0){ r++; n/=num[j];}
ans*=(2*r+1);
}
if(n>1) ans*=3;
printf("Scenario #%d:\n",i);
printf("%d\n\n",(ans+1)/2);
}
return 0;
}
最终结果要+1再/2,从
1 / 5 + 1 / 20 = 1 / 4
1 / 6 + 1 / 12 = 1 / 4
1 / 8 + 1 / 8 = 1 / 4
可以看出。。
有5,20,6,12,8五个。可以组合成(5+1)/2 = 3种