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 '
'
#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;
}
}