LightOJ 1236. Pairs Forming LCM
Pairs Forming LCM
题意
给定整数 \(n\) ,求出有多少组合(i, j),使得 \(LCM(i, j) = n\)。
\(1 \le n \le 10^{14}\)
分析
首先有 \(1 \le i, j \le n\)。
对 \(n\) 分解质因数 \(n = p_1^{e_1} \times p_2^{e_2} \times p_3^{e_3} ... \times p_k^{e_k}\)。
现在取 \(n\) 的两个因子 \(a, b\) 。
\(a = p_1^{a_1} \times p_2^{a_2} ... \times p_k^{a_k}\)
\(b = p_1^{b_1} \times p_2^{b_2} ... \times p_k^{b_k}\)
容易发现:
\(GCD(a, b) = p_1^{min(a_1, b_1)} \times p_2^{min(a_2, b_2)} ... \times p_k^{min(a_k, b_k)}\)
\(LCM(a, b) = p_1^{max(a_1, b_1)} \times p_2^{max(a_2, b_2)} ... \times p_k^{max(a_k, b_k)}\)
现在要求 \(LCM(a, b) = n\) ,即:$max(a_1, b_1) = e_1, max(a_2, b_2) = e_2 ... $
分类,如果 \(a_1 = e_1\) ,则 \(b_1 = [0, e_1]\) 有 \(e_1+1\) 种方案,同理 \(a_1\) 也有 \(e_1+1\) 种方案,除去 \(a_1=b_1=e_1\),则一共有
\(2 * (e_1 + 1) + 1\) 种方案。
由于 \(n \le 10^{14}\) 我们只筛去 \(\sqrt{n}\) 内的质数,再判断是否存在大于 \(\sqrt{n}\) 的质因数(最多一个)。
由于要求 \(a \le b\) ,只需要最后除以2即可。至于为什么要加一,是因为 \(a \lt b\) 和 \(a \gt b\) 是对称的,但是还有一种方案是 \(a = b = n\) 。
Code
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <limits.h>
using namespace std;
typedef unsigned long long ll;
const int N = 10000010;
const ll limit = ~0ll >> 1;
int prime[N / 10], cnt; // 质数定理,可以少开空间
bool st[N];
void get_primes () {
for (int i = 2; i < N; i ++ ) {
if (!st[i]) prime[cnt ++ ] = i;
for (int j = 0; i * prime[j] < N; j ++ ) {
st[i * prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
}
signed main ()
{
get_primes();
int T; cin >> T; for (int i = 1; i <= T; i ++ )
{
ll n; cin >> n;
ll ans = 1;
// 质因数分解
for (int i = 0; i < cnt && prime[i] <= n / prime[i]; i ++ )
{
ll sum = 0;
while(n % prime[i] == 0) sum ++ , n /= prime[i];
ans *= 2 * sum + 1;
}
if (n > 1) ans *= 2 * 1 + 1; // 最多存在一个大于 sqrt(n) 的质因子,单独判断
cout << "Case " << i << ": " << ans / 2 + 1 << '\n';
}
return 0;
}