链接: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/x+1/y=1/n 得 (n-x)*(n-y)=n^2
又因为x<=y,x、y、n均为正整数,所以原问题等价于求n^2的因子个数
我们可以使用”因数个数定理”来求解。
对大于1的正整数n = p1^a1p2^a2…pk^ak,则n的因数个数为(a1+1)(a2+1)…(ak+1)
注意到在这个问题中我们求的是n^2的因数个数,而n的因子肯定也是n^的因子所以我们可以先分解n,然后ans=(2a1+1)(2a2+1)…(2ak+1)
还有一个坑,由于数组大小的限制,欧拉筛求不出1e7以上的素数。这个坑很好解决,如果当n已经除以所有1e6以下的因子但还没有除尽,这时它肯定只是一个素数了(用反证法,如果是两个大于1e6的素数的乘积,则它大于1e12,而n最大才是1e9,矛盾)。所以如果没除尽,直接ans*=3就可以了。
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 
 | #include <cstdio>#include <algorithm>
 #include <iostream>
 #include <set>
 #include <vector>
 #include <cstring>
 #include <queue>
 #include <stack>
 #include <ctype.h>
 #include <map>
 
 using namespace std;
 typedef unsigned long long ull;
 
 const ull mod = 1e9+7;
 
 const int maxn = 1000000;
 ull prime[maxn], notPrime[maxn], priCnt=0;
 
 void getPrime() {
 for (int i = 2; i < maxn; i++) {
 if (!notPrime[i])
 prime[priCnt++] = i;
 for (int j = 0; j < priCnt && i * prime[j] < maxn; j++) {
 notPrime[i * prime[j]] = 1;
 if (i % prime[j] == 0) break;
 }
 }
 }
 
 int main() {
 #ifndef ONLINE_JUDGE
 freopen("in.txt", "r", stdin);
 #endif
 getPrime();
 ull t;
 scanf("%llu", &t);
 while (t--) {
 ull n;
 scanf("%llu", &n);
 ull ans = 1;
 for (int i = 0; i < priCnt && prime[i] <= n; i++) {
 ull a = 0;
 while (n % prime[i] == 0) {
 n /= prime[i];
 a++;
 }
 ans = ans * ( k * a + 1 );
 }
 if (n!=1){
 ans  = ans*3;
 }
 printf("%llu\n", (ans + 1) / 2);
 }
 return 0;
 }
 
 |