hdu 1299 Diophantus of Alexandria

Diophantus of Alexandria

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?
 
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
思路(转别人的,写的很好):
因为1/x + 1/y = 1/n,则x+y / xy = 1/n,令x = n+a, y = n+b(x,y必定大于n),则等式可以化成a*b = n^2;因为a,b都是整数,所以a,b必定是n^2的约数,找出n^2的所有约数,即可找出所有满足题意的解。由于要满足x <= y所以只需找出a <= b的解的个数即可,设约数个数为num,则答案为(num+1)/2。那么如何找出n^2的约数个数呢?因为n <= 10^9,则n^2是一个很大的数,在时间和空间上都不允许直接操作,考虑到任何整数n都可以表示为 n = p1^e1*p2^e2*..pn^en,其中p1,p2..,pn都为素数,并且n的约数个数为 (1+e1)*(1+e2)*...(1+en);所以n^2 = (p1^e1*p2^e2...pn^en)^2 = p1^2e1*p2^2e2...*pn^2en,故其约数个数为(1+2e1)*(1+2e2)*...(1+2en);所以只需求出n的约数个数即可,每次求出ek(k=1,2,3,4..)的时候,将结果乘上2即可。同时,要找10^9以内的素数,范围比较大,其实只需求出sqrt(10^9)以内的素数即可,因为大于sqrt(10^9)的素数必定是以自己单独存在的,也就是说,若该素数为pk,则ek必定等于1.(pk^2>10^9,已经比n大了)
 
 我的代码:
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int p[40005];
bool v[40005];
int k;
void prime()
{
    int i,j;
    k=0;
    memset(v,0,sizeof(v));
    for(i=2;i<200;i++)
    {
        if(!v[i])
        for(j=i*i;j<40000;j+=i)
         v[j]=true;
         for(i=2;i<40000;i++)
            if(!v[i]) p[k++]=i;
    }
}
int fg(int n)
{
    int i,ret=1;
    for(i=0;i<k&&p[i]<n;i++)
    {
        int t=0;
        while(n%p[i]==0)
        {
            n=n/p[i];
            t++;
        }
        ret*=(t*2+1);
    }
    if(n>1) ret=ret*3;
    return ret;
}

int main()
{
    prime();
    int n,x,i;
    while(scanf("%d",&n)!=EOF)
    for(i=1;i<=n;i++)
    {
        scanf("%d",&x);
        printf("Scenario #%d:\n",i);
        printf("%d\n\n",(fg(x)+1)/2);
    }
    return 0;
}
View Code

 

posted on 2013-07-10 20:33  _洋洋  阅读(202)  评论(0编辑  收藏  举报

导航