F 等式
链接:https://www.nowcoder.com/acm/contest/90/F
来源:牛客网
题目描述
给定n,求1/x + 1/y = 1/n (x<=y)的解数。(x、y、n均为正整数)
输入描述:
在第一行输入一个正整数T。
接下来有T行,每行输入一个正整数n,请求出符合该方程要求的解数。
(1<=n<=1e9)
输出描述:
输出符合该方程要求的解数。
示例1
输入
3
1
20180101
1000000000
输出
1
5
181
tags:
数学题,推公式
1/x+1/y = 1/n
(x+y)/xy = 1/n
nx+ny = xy
ny = x(y-n)
x = ny/(y-n)
x = ( n(y-n)+n*n ) / (y-n)
x = n + n*n/(y-n)
推到这里,就会发现,我们只要找出 n*n 有多少个因子即可。但 n*n 太大,我们先用算术基本定理算出 n 的因子数,再乘两倍即是 n*n 的因子数。
比如 :
n=12 , n*n = 12*12
12 有质因子 2 和3,可分解出 2 有 2 个,3 有 1 个,因子数为 (2+1)*(1+1)个; 而对于n*n ,则可分解出 2 有 2*2 个, 3 有 1*2 个因子数为(2*2+1)*(1*2+1)个。
求出 n*n 的因子数,因为 x<=y ,则答案就是除以 2 。
注意, 1/x+1/y=1/n, 肯定有 x==y 的情况,所以最后注意这个点。
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = 200005;
ll n;
ll solve() {
ll tn = n, ret = 1;
for(ll i=2; i*i<=tn; ++i)
{
ll sum =0;
while(tn%i==0) ++sum, tn/=i;
ret *= (sum*2+1);
}
if(tn != 1) ret *= 3;
return (ret-1)/2+1;
}
int main()
{
int T; scanf("%d", &T);
while(T--)
{
scanf("%lld", &n);
printf("%lld
", solve());
}
return 0;
}