洛谷 P2398. GCD SUM

题目描述

i=1nj=1ngcd(i,j)

输入:
2

输出:
5

算法1 线性筛 O(n)

将式子变形:

要知道一个前置定理
d|nφ(d)=n

艾弗森约定:
定义  [P] = {P is true 1 P is false 0

 

 

i=1nj=1ngcd(i,j)

 

=i=1nj=1nk|gcd(i,j)φ(k)

 

=i=1nj=1nk|i,k|jφ(k)

 

=k=1nφ(k)i=1nj=1n[k|i][k|j]


=k=1nφ(k)nknk

就可以O(n)预处理欧拉函数然后O(n)数论分块过掉了

Code:

复制代码
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5 + 5; typedef long long LL; int n; int primes[N], cnt; LL phi[N], sum[N]; bool st[N]; void init(int n) { phi[1] = 1; for (int i = 2; i <= n; i ++ ) { if (!st[i]) { primes[cnt ++ ] = i; phi[i] = i - 1; } for (int j = 0; primes[j] <= n / i; j ++ ) { st[primes[j] * i] = true; if (i % primes[j] == 0) { phi[primes[j] * i] = phi[i] * primes[j]; break; } phi[primes[j] * i] = phi[i] * (primes[j] - 1); } } for (int i = 1; i <= n; i ++ ) sum[i] = sum[i - 1] + phi[i]; } int main() { init(N - 1); scanf("%d", &n); LL res = 0; for (int l = 1, r; l <= n; l = r + 1) { r = n / (n / l); res += (sum[r] - sum[l - 1]) * (n / l) * (n / l); } printf("%lld", res); return 0; }
复制代码

 


__EOF__

本文作者xyy's blog
本文链接https://www.cnblogs.com/xyy-yyds/p/17281144.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   xuyiyang  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示