POJ 2917 Diophantus of Alexandria

Diophantus of Alexandria
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3982 Accepted: 1377

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 xn + yn = zn. 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)

Diophantus is interested in the following question: for a given n, how many distinct solutions (i. e., solutions satisfying xy) does equation (1) have? For example, for n = 4, there are exactly three distinct solutions:

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 ≤ 109).

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大了)。

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #define MAX 40005
 5 
 6 using namespace std;
 7 
 8 int prime[MAX];
 9 bool vis[MAX];
10 int idx;
11 
12 void findPrime()  //筛选sqrt(10^9)内的素数
13 {
14     memset(vis,0,sizeof(vis));
15     idx = 0;
16     for(int i=2; i<=200; i++)
17         if(!vis[i])
18             for(int j=i*i; j<=40000; j+=i)
19                 vis[j] = true;
20     for(int i=2; i<=40005; i++)
21         if(!vis[i])
22             prime[idx++] = i;
23 }
24 
25 int cal(int n)  //计算因子个数
26 {
27     int ret = 1;
28     for(int i=0; i<idx && prime[i]<=n; i++)
29     {
30         int time = 0;
31         while(n % prime[i] == 0)
32         {
33             n /= prime[i];
34             time ++;
35         }
36         ret *= (1+time*2);
37     }
38     if(n > 1)  //除不尽,说明n是大于sqrt(10^9)的素数,ret *= (1 + 2*1);
39         ret *= 3;  
40     return ret;
41 }
42 
43 int main()
44 {
45     findPrime();
46     int Case;
47     scanf("%d",&Case);
48     for(int ca = 1; ca <= Case; ca ++)
49     {
50         int n;
51         scanf("%d",&n);
52         int ans = cal(n);
53         printf("Scenario #%d:\n",ca);
54         printf("%d\n\n",(ans+1)/2);
55     }
56     return 0;
57 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值