神仙反演...推了一晚上式子 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;
} 
京公网安备 11010502036488号