「PE#530」GCD of Divisors - 莫比乌斯反演

神仙反演...推了一晚上式子 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; 
}
Shq的题解专栏 文章被收录于专栏

之前的一些文章,来搬(chao)运(leng)下(fan),可能会再更新一些文章

全部评论

相关推荐

03-03 23:12
已编辑
北京邮电大学 Java
书海为家:我来给一点点小建议,因为毕竟还在学校不像工作几年的老鸟有丰富的项目经验,面试官在面试在校生的时候更关注咱们同学的做事逻辑和思路,所以最好在简历中描述下自己做过项目的完整过程,比如需求怎么来的,你对需求的解读,你想到的解决办法,遇到困难如何找人求助,最终项目做成了什么程度,你从中收获了哪些技能,你有什么感悟。
你的简历改到第几版了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务