LightOJ1236 - Pairs Forming LCM (唯一分解定理)
Description
题目大意:就是求\(\sum_{i=1}^{n}{\sum_{j=i}^{n}{[lcm(i, j) == n]}}\)的结果。
思路
网上有篇博客对这题解释得非常好,记录一下。
看到这个式子,就想到应该和n的因子有关。
这里有一个结论
假设
\[n = p_1^{k_1} \cdot p_2^{k_1} ... p_n^{k_n}
\]
设a, b都是n的因子,有
\[a = p_1^{x_1} \cdot p_2^{x_1} ... p_n^{x_n}
\]
\[b = p_1^{y_1} \cdot p_2^{y_1} ... p_n^{y_n}
\]
为了形式的统一,当因子不含质因子p时,令它的次数x=0。
就有
\[lcm(a, b)=p1^{\max(x_1, y_1)} \cdot p_2^{\max(x_2,y_2)}...p_n^{\max(x_n, y_n)}
\]
\[\gcd(a, b)=p1^{\min(x_1, y_1)} \cdot p_2^{\min(x_2,y_2)}...p_n^{\min(x_n, y_n)}
\]
所以对于\(lcm(a, b) == n\), 就要求这里的\(max(x_i, y_i) = k_i\),即这两个数必须有一个是\(k_i\),另一个可以取\([0, k_i]\)。
对于每个\(p_i\),次数有\(2k_i + 1\)种选择。故一共有\(\prod_{i=1}^n{2k_i+1}\)种选择。由于题目要求i<=j,所以最后要除以2,再加上\(i=j=n\)的一种情况。
所以\(ans=\frac{\prod_{i=1}^n{2k_i+1}}{2}+1\)
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <stack>
#include <deque>
#include <cmath>
#include <iomanip>
#include <cctype>
#define endl '\n'
#define IOS std::ios::sync_with_stdio(0);
#define pb push_back
#define mp make_pair
#define seteps(N) fixed << setprecision(N)
typedef long long ll;
using namespace std;
/*-----------------------------------------------------------------*/
#define INF 0x3f3f3f3f
const int N = 1e7 + 10;
const double eps = 1e-8;
vector<int> prime;
bool isnp[N];
int main() {
IOS;
//FO;
for(int i = 2; i < N; i++) {
if(!isnp[i]) {
prime.push_back(i);
for(int j = 2 * i; j < N; j += i) {
isnp[j] = 1;
}
}
}
int t;
cin >> t;
int cas = 0;
while(t--) {
ll n;
cin >> n;
ll ans = 1;
ll tn = n;
for(int i = 0; i < prime.size(); i++) {
if(1ll * prime[i] * prime[i] > n) break;
if(tn % prime[i] == 0) {
int cnt = 0;
while(tn % prime[i] == 0) {
tn /= prime[i];
cnt++;
}
ans = ans * (2 * cnt + 1);
}
}
if(tn != 1) {
ans = ans * 3;
}
ans /= 2;
ans += 1;
cout << "Case " << ++cas << ": " << ans << endl;
}
}