第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛 F 数学

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\n", solve());
    }

    return 0;
}

posted @ 2018-03-27 22:56  v9fly  阅读(123)  评论(0编辑  收藏  举报