HDOJ Problem

题意:等式 1 / x + 1 / y = 1 / n (x, y, n ∈ N+ (1) 且 x <= y) ,给出 n,求有多少满足该式子的解。(1 <= n <= 1e9)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1299

分析:x,y肯定都满足 n<x<=y; 设 x = n + k; 带入上式得 :1/y = k/(n2+n*k); 即 k要整除 (n2+n*k); 又 k 一定整除 n*k; 即求 k 整除 n2; 即求 n2 的因数个数。

注意:   1.数据范围太大,不能直接分解n2

           2.利用唯一分解定理的推论求因数个数:对于一个数n,由唯一分解定理得x=a1^k1*a2^k2...*an^kn.(ai为素数)。

              则x的因子个数为(k1+1)*(k2+1)*...*(kn+1)。

    3.推出:x2=(a1^k1*a2^k2......*an^kn)2. 则 n2的因子个数为 (2*k1+1)*(2*k2+1)*......*(2*kn+1)。

    4.又x<=y, 则 ans=(ans+1)/2;(ans是n^2的因数个数)。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 using namespace std;
 7 #define ll long long
 8 #define mx 100000
 9 int prime[mx];
10 int vis[mx];
11 void getprime()
12 {
13     int m=sqrt(mx+0.5);
14     for(int i=2;i<=m;i++)
15     {
16         if(!vis[i])
17         {
18             for(int j=i*i;j<mx;j+=i)
19                 vis[j]=1;
20         }
21     }
22     int cnt=0;
23     for(int i=2;i<mx;i++)
24         if(!vis[i])
25            prime[cnt++]=i;
26 }
27 int fun(int num)
28 {
29     int ans=1;
30     int qs=sqrt(num+0.5);
31     //cout<<qs<<endl;
32     for(int i=0;prime[i]<=qs;i++) //设a=n+x,b=n+y。得到n^2=x*y
33     {
34         int cnt=0;
35         while(!(num%prime[i])&&num>1)
36         {
37             num/=prime[i];
38             cnt++;
39         }
40         ans*=(2*cnt+1);    //注意:由于n的范围比较大,所以我们不能直接将n^2分解,
41     }                      //我们可以通过分解n从而得知n^2分解的情况,由此计算答案
42     if(num!=1)
43         ans*=3;
44     return ans;
45 }
46 int main()
47 {
48    getprime();
49    int t;
50    scanf("%d",&t);
51    for(int k=1;k<=t;k++)
52    {
53        int n;
54        scanf("%d",&n);
55        int ans=fun(n);
56        printf("Scenario #%d:
%d

",k,(ans+1)/2);
57    }
58    return 0;
59 }
原文地址:https://www.cnblogs.com/tristatl/p/6012571.html