来源
Description
这一次,那几个师妹给sharp出了一个题目:给定一个正整数N,求1/X+1/Y= 1/N的所有正整数解.sharp哈哈笑了两声,很简单的题目嘛....但是他一听数据范围就傻眼了,N最大可能是999999999!!!聪明的你能帮帮可怜的sharp吗?好让他不那么丢脸.
Input
第一行输入一个正整数M,下面有M行,每一行都是一个正整数N.
Output
输出共M行,每行都是方程解的个数.
Sample Input
2
1
2
Sample Output
1
3
前置知识:
-
算术基本定理
任何一个大于1的自然数N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积
[n=a_1^{b_1}*a_2^{b_2}*a_3^{b_3}... ] -
设N=ab(N,a,b均为正整数),求a,b的所有可能情况数sum
思考一下,a,b两者此消彼长,当a为最小,b为最大;a最大,b最小,且{(a,b|ain N^*,b in N^*)}.那么转换一下思路,其实我们只要求a,b的取值范围即可.由算术基本定理可知,n是由多个素数组合而成的,那么a,b的取值范围也正是他们组合的结果.再转换一下思路——这是一个排列组合问题,每次我们选择(c_i(0<=c_i<=b_i))个(a_i)构成a(剩下的数构成b),那么
[sum=a_{sum}=(b_1+1)*(b_2+1)*(b_3+1)... ]
分析问题:
- 先对(frac{1}{x}+frac{1}{y}=frac{1}{n})进行整理.由于等式n为正整数,要保证等式平衡,则x>n,y>n,即x=n+a(a>0),y=n+b(b>0).代入等式可得(n^2=ab)
- 要求方程的解我们只要求出在给定的n下所有ab可能的值即可,这个问题也就是我们的前置知识2所求的内容.当然,这里有点小区别,由于(n^2=ab=a_1^{2b_1}*a_2^{2b_2}*a_3^{2b_3}...,则sum=(2*b_1+1)*(2*b_2+1)*(2*b_3+1)...)
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll getNum(ll n);
int main()
{
ll n,num,ans;
scanf("%lld",&num);
while(num--){
scanf("%lld",&n);
ans = getNum(n);
printf("%lld
",ans);
}
return 0;
}
ll getNum(ll n) //计算n中的个数
{
ll num=1,prime=2;
while(n>1){
int temp=0;
while(n%prime==0){
n/=prime;
temp++;
}
num*=(2*temp+1);
if(n!=1&&prime*prime>n){
num*=3;
break;
}
prime++;
}
return num;
}