Diophantus of Alexandria
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2913 Accepted Submission(s): 1125
Problem Description
Diophantus of Alexandria was an egypt mathematician living in Alexandria. He was one of the first mathematicians to study equations where variables were restricted to integral values. In honor of him, these equations are commonly called diophantine equations. One of the most famous diophantine equation is x^n + y^n = z^n. Fermat suggested that for n > 2, there are no solutions with positive integral values for x, y and z. A proof of this theorem (called Fermat's last theorem) was found only recently by Andrew Wiles.
Consider the following diophantine equation:
1 / x + 1 / y = 1 / n where x, y, n ∈ N+ (1)
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 / 5 + 1 / 20 = 1 / 4
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?
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?
Input
The first line contains the number of scenarios. Each scenario consists of one line containing a single number n (1 ≤ n ≤ 10^9).
Output
The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Next, print a single line with the number of distinct solutions of equation (1) for the given value of n. Terminate each scenario with a blank line.
Sample Input
2 4 1260
Sample Output
Scenario #1: 3 Scenario #2: 113
Source
此题看起来较难,不过做到后边就知道此题的难点在于如何快速判断质数,这里就不说了,我也不是很熟悉,这里分享一下这道题的思路:
设1/a=1/q+1/m;
同时乘以a*q得q-a=q*a/m;
同时除以q*a得(q-a)/q*a=1/m;
设q-a=i;
的i/((a+i)*a);
因为分子为1,所以i一定能被(a+i)*a整除,即a*a能整除i,此题化为n*n有多少约数;
如何判断一个数的约数的个数:
这里有点母函数的意思,不过提取精要部分:
n=a1^m1*b2^m2*....*ak^mk(a1,....ak是互不相同的质数)
则因数中取a1有0,1,2,....,m1,m1+1种可能,同理ak有mk+1种可能,不同可能就是不同的因数,
所以因数的个数有(m1+1)(m2+1)....(mk+1)
++++++
但是不需要求到n*n只需要求到n即可;
看下边:
for(i=2;i<=n;i++)
{
flag=0;
while(n%i==0)
{
n=n/i;
flag++;
}
ans*=(2*flag+1);//n*n里边肯定就有2*flag个i了;
}
但是这样会超时,考虑最坏的情况,一个数很接近10亿(题中的上限),还是质数,则就会超时,但是可以判断出n为质数的话,n*n只有两个约数,一个1,一个n;
所以此题成为如何快速判断质数了:
附代码:
#include<stdio.h>
#include<math.h>
int a[5000];
int main(void)
{
int t,g;
scanf("%d",&t);
int i,m=1;
a[0]=2;
for(i=3;i<33335;i+=2)
{
int j;
for(j=0;j<m;++j)
if(i%a[j]==0)
break;
if(j==m)
a[m++]=i;
}
for(g=1;g<=t;g++)
{
int n,j=0;
scanf("%d",&n);
int factor[100]={0};
for(i=0;n>1&&i<m;i++)
{
while(n%a[i]==0&&n>1)
{
factor[j]++;
n/=a[i];
}
if(factor[j]!=0)
j++;
}
if(n!=1)
factor[j++]++;
int result=1;
for(i=0;i<j;i++)
result*=(factor[i]*2+1);
printf("Scenario #%d:\n",g);
printf("%d\n\n",(result+1)/2);
}
return 0;
}