p1629【找分子】
描述 Description
给定n(2≤n≤10^9)值,要求x、y均为正整数,且x<y,并且满足1/x+1/y=1/n.
编程统计有多少对这样的x和y。
输入格式 Input Format
一个整数n。
输出格式 Output Format
一个整数,表示相应的方法数是多少。
样例输入 Sample Input
6
样例输出 Sample Output
4
时间限制 Time Limitation
1s
注释 Hint
经典数学题目
来源 Source
经典问题
思路:先用筛法求出50000以内的素数(习惯50000了(筛法真的好用)),因为我们要对1/n分解,这里只分成了1/x+1/y=1/n,又因为x,y,n全为正整数
且x<y。所以可知1/n=1/x+1/y => xy=nx+ny => n^2=(x-n)(y-n);所以问题就成为了求n^2的所有因子个数除以2.
我们又可以用约束和定理等到因为,n=p1^a1*p2^a2...pk^ak,所以n的所有因数的个数为(a1+1)(a2+1)...(ak+1)。所以直接就就好了
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int a[5510000]; bool f[5510000]; int prime[5510000]; int main() { long long n; cin>>n; memset(f,1,sizeof(f)); memset(a,0,sizeof(a)); for(int i=2;i<=500000;i++)//筛法求素数表 { if(f[i]) { for(int j=i+i;j<=500000;j+=i) { f[j]=false; } } } long long len=0; int m=n; for(int i=2;i<=500000;i++) if(f[i]) prime[++len]=i; int l=0; for(int i=1;i<=len&&prime[i]<=n;i++)//记录每个素数因数有几个 { if(n%prime[i]==0) l++; while(n%prime[i]==0) { a[l]++; n/=prime[i]; } } if(n>1) a[++l]=1; long long ans=1; for(int i=1;i<=l;i++) { ans*=(2*a[i]+1); } if(ans%2==0) cout<<ans/2<<endl; else cout<<(ans-1)/2<<endl; return 0; }