传送门
求 ∑ i = 1 n ∑ j = i n [ l c m ( i , j ) = = n ] , n ≤ 1 e 14 \sum_{i=1}^{n}\sum_{j=i}^{n}[lcm(i,j)==n],n\leq 1e^{14} ∑i=1n∑j=in[lcm(i,j)==n],n≤1e14
一开始以为是莫比乌斯反演,推了一下发现推不动了。尝试找下规律,对 n n n质因数分解 n = p 1 a 1 p 2 a 2 . . . p n a n n=p_1^{ a_1}p_2^{ a_2}...p_n^{ a_n} n=p1a1p2a2...pnan,然后考虑 l c m lcm lcm在质因数分解下的意义,实际上就是 i ∗ j i*j i∗j后每一个素数一定有 p k m a x ( b i , b j ) = p k a k p_k^{max(b_i,b_j)}=p_k^{a_k} pkmax(bi,bj)=pkak,即 m a x ( b i , b j ) = a k max(b_i,b_j)=a_k max(bi,bj)=ak。这样感觉规律就在眼前了,我尝试打表却还是没找出来…
实际上是有技巧的,考虑 ∑ i = 1 n ∑ j = 1 n [ l c m ( i , j ) = = n ] \sum_{i=1}^{n}\sum_{j=1}^{n}[lcm(i,j)==n] ∑i=1n∑j=1n[lcm(i,j)==n],这时再考虑上面的想法,显然是每一个 p k a k p_k^{a_k} pkak一定在 i , j i,j i,j其中之一上可以分解得到,对于另外一个数那么可选择的 p k p_k pk的指数的取值范围就是 [ 0 , a k ] [0,a_k] [0,ak],那么考虑乘法原理最后的答案就是 ( 2 a 1 + 1 ) ( 2 a 2 + 1 ) . . . ( 2 a n + 1 ) (2a_1+1)(2a_2+1)...(2a_n+1) (2a1+1)(2a2+1)...(2an+1)
但是本题相对于上述答案不同的是只有 j ≥ i j\geq i j≥i,然而当 i = j i=j i=j时显然只有 i = j = n i=j=n i=j=n这一种情况,考虑容斥定理,且上述若干个奇数的乘积一定是奇数,那么 j ≥ i j \geq i j≥i的贡献就是 ( a n s − 1 ) / 2 (ans-1)/2 (ans−1)/2,那么最终的答案就是 ( a n s − 1 ) / 2 + 1 (ans-1)/2+1 (ans−1)/2+1
这题数据巨毒瘤,我用了很久自认为完美无缺的Pollard-Rho板子被卡了
// // Created by Happig on 2020/10/21 // #include <bits/stdc++.h> #include <unordered_map> #include <unordered_set> using namespace std; #define fi first #define se second #define pb push_back #define ins insert #define Vector Point #define ENDL "\n" #define lowbit(x) (x&(-x)) #define mkp(x, y) make_pair(x,y) #define mem(a, x) memset(a,x,sizeof a); typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<double, double> pdd; const double eps = 1e-8; const double pi = acos(-1.0); const int inf = 0x3f3f3f3f; const double dinf = 1e300; const ll INF = 1e18; const int Mod = 1e9 + 7; const int maxn = 1e7 + 10; int prime[maxn / 3], cnt; bitset<maxn> vis; void euler() { vis[1] = 1; for (int i = 2; i < maxn; i++) { if (!vis[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && 1LL * i * prime[j] < maxn; j++) { vis[i * prime[j]] = 1; if (i % prime[j] == 0) break; } } } ll solve(ll n) { int m = sqrt(n + 0.5); ll ans = 1; for (int i = 1; i <= cnt && prime[i] <= m; i++) { if (n % prime[i] == 0) { ll res = 0; while (n % prime[i] == 0) { res++; n /= prime[i]; } ans *= 2 * res + 1; } if (n == 1) break; } if (n > 1) ans *= 3; return (ans - 1) / 2 + 1; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int T, kase = 0; ll n; euler(); cin >> T; while (T--) { cin >> n; cout << "Case " << ++kase << ": " << solve(n) << ENDL; } return 0; }