神仙反演...推了一晚上式子 Link
简要题意
已知
求
GCD of Divisors
Every divisor of a number n has a complementary divisor .
Let be the sum of the greatest common divisor of and over all positive divisors of , that is
Let be the summatory function of , that is
You are given that and .
Find .
题解
题目就是要求
然后反演套路 (枚举 )
注意到 且 , 所以有 , 将这个提出来:
反演.
交换
像上面一样提出 , 就有
其中 正是 (约数个数和)
由于 ,
故
所以考虑构造前面的卷积, 令 . 注意到倒数第二个 是枚举的范围, 故第一层只用枚举到 即可:
后面这个东西直接求就没了....实际上可以换枚举方式来解决:
后面的式子就可以每次 做, 对 求和就是相当于一个调和级数, 所以时间复杂度就是
代码:
#include <bits/stdc++.h> #define int long long const int N = 31622777 + 10; // sqrt(1e15) int cnt; int pri[N]; int mu[N + 10]; int phi[N + 10]; bool vis[N + 10]; void pre (int n) { phi[1] = 1; for (int i = 2; i <= n; i++) { if (!vis[i]) pri[++cnt] = i, phi[i] = i - 1; for (int j = 1; j <= cnt && i * pri[j] <= n; j++) { vis[i * pri[j]] = 1; if (i % pri[j] == 0) { phi[i * pri[j]] = phi[i] * pri[j]; break; } phi[i * pri[j]] = phi[i] * (pri[j] - 1); } } } int sum (int x) { int ret = 0; for (int l = 1, r; l <= x; l = r + 1) { r = x / (x / l); ret += (r - l + 1) * (x / l); } return ret; } signed main () { int n, ans = 0; n = 1000000000000000ll; // scanf("%lld", &n); int limit = sqrt(n) + 1; pre(limit); for (int i = 1; i <= limit; i++) ans += phi[i] * sum(n / (i * i)); printf("%lld", ans); return 0; }