HDOJ Problem - 1299
Posted tristaTL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ Problem - 1299相关的知识,希望对你有一定的参考价值。
题意:等式 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:\n%d\n\n",k,(ans+1)/2); 57 } 58 return 0; 59 }
以上是关于HDOJ Problem - 1299的主要内容,如果未能解决你的问题,请参考以下文章