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;
}

 

posted @ 2017-08-22 19:13  列車員lcy  阅读(227)  评论(0编辑  收藏  举报