HDU 1299 Diophantus of Alexandria(数论)

Description
给出一个正整数n,问有多少对正整数对(x,y)满足1/x+1/y=1/n
Input
第一行为一整数T表示用例组数,每组用例为一正整数n
Output
对于每组用例,输出满足条件的(x,y)对数(注意(1,2)和(2,1)是一种组合),每组用例后输出一空行
Sample Input
2
4
1260
Sample Output
Scenario #1:
3

Scenario #2:
113

Solution
由1/x+1/y=1/n得x=ny/(y-n),显然x,y>n,故不妨令y=n+k,那么x=n*n/k+n,由x是正整数知所有满足条件的k都是n*n的因子,故问题转化为求n*n的因子数,而由n=p1^a1*p2^a2*…pm^am及n*n=p1^(2*a1)*p2^(2*a2)pm^(2*am)知,n*n的因子数num=(2*a1+1)(2*a2+1)(2*am+1),所以对n素因子分解即可,注意因为不考虑x和y的顺序所以结果为ans=(num+1)/2
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define maxn 55555
int mark[maxn],prime[maxn],res;//prime存储素数,从0开始,mark[i]表示i的最小素因数 
void get_prime(int n)//素数线性筛法,得到n以内所有素数共res个 
{
    memset(mark,0,sizeof(mark));
    res=0;
    for(int i=2;i<=n;i++)
    {
        if(!mark[i]) 
            mark[i]=prime[res++]=i;
        for(int j=0;j<res&&prime[j]*i<=n;j++)
        {
            mark[i*prime[j]]=prime[j];
            if(i%prime[j]==0) 
                break;
        }
    }
} 
int main()
{
    get_prime(maxn-1);
    int t,n,ans,cnt,Case=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ans=1;
        for(int i=0;i<res&&prime[i]*prime[i]<=n;i++)
        {
            cnt=0;
            if(n%prime[i]==0)
                while(n%prime[i]==0)
                    n/=prime[i],cnt++;
            ans*=(2*cnt+1); 
        }
        if(n>1)ans*=3;
        printf("Scenario #%d:\n",Case++);
        printf("%d\n\n",(ans+1)/2);
    }
    return 0;
} 

你可能感兴趣的:(HDU 1299 Diophantus of Alexandria(数论))