【BZOJ】【2705】【SDOI2012】Longge的问题
欧拉函数/狄利克雷卷积/积性函数
2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1275 Solved: 820
[Submit][Status][Discuss]
Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Input
一个整数,为N。
Output
一个整数,为所求的答案。
Sample Input
6
Sample Output
15
HINT
【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
Source
掉到莫比乌斯反演的坑里无法自拔,问了zyf&在网上看了题解才做出来TAT……我果然好弱
这个题是要求∑nx=1gcd(x,n),考虑它的实际意义,我们可以得到ans=\sum_{i|n}i*\varphi(\frac{n}{i})
但是明显φ函数我们是没法预处理的……(\frac{n}{i}这玩意太大了),但考虑到n的约数不会太多,所以我们可以边找因数边计算φ。

1 /************************************************************** 2 Problem: 2705 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:16 ms 7 Memory:804 kb 8 ****************************************************************/ 9 10 //BZOJ 2705 11 #include<cmath> 12 #include<cstdio> 13 #define F(i,j,n) for(int i=j;i<=n;i++) 14 typedef long long LL; 15 LL phi(LL n){ 16 int ret=1,i; 17 for(int i=2;i*i<=n;i++){ 18 if (n%i==0){ 19 n/=i; ret*=i-1; 20 while(n%i==0) n/=i,ret*=i; 21 } 22 } 23 if (n>1) ret*=n-1; 24 return ret; 25 } 26 int main(){ 27 int n; 28 scanf("%d",&n); 29 long long ans=0; 30 for(int i=1;i*i<=n;i++) 31 if(n%i==0){ 32 ans+=(LL)i*phi(n/i); 33 if (i*i<n) ans+=(LL)n/i*phi(i); 34 } 35 printf("%lld\n",ans); 36 return 0; 37 }
但是其实对于这个函数\sum_{i|n} i*\varphi(\frac{n}{i})是满足积性的,因为它就是id(x)=x和\varphi(x)这两个函数的狄利克雷卷积,那么……(贴个网上的图片)

1 /************************************************************** 2 Problem: 2705 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:8 ms 7 Memory:816 kb 8 ****************************************************************/ 9 10 //BZOJ 2705 11 #include<cmath> 12 #include<cstdio> 13 #define F(i,j,n) for(int i=j;i<=n;i++) 14 int main(){ 15 int n; 16 scanf("%d",&n); 17 long long ans=n; 18 F(i,2,sqrt(n)){ 19 if(n%i==0){ 20 int k=0; 21 for(k;n%i==0;k++,n/=i); 22 ans+=ans*(i-1)*k/i; 23 } 24 } 25 if (n!=1) ans+=ans*(n-1)*1/n; 26 printf("%lld\n",ans); 27 return 0; 28 }
P.S.但是这个【乘起来】的过程我在网上没找到啊……写法好诡异我理解不了……所以我机(sha)智(bi)地改了一个利用快速幂的版本= =耗时居然一样……如果有哪位路过的大牛搞明白了前面那个加法版本的意思的话请留言教我一下,万分感谢。

1 /************************************************************** 2 Problem: 2705 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:8 ms 7 Memory:816 kb 8 ****************************************************************/ 9 10 //BZOJ 2705 11 #include<cmath> 12 #include<cstdio> 13 #define F(i,j,n) for(int i=j;i<=n;i++) 14 typedef long long LL; 15 LL Pow(LL a,LL b){ 16 LL r=1; 17 for(;b;b>>=1,a*=a)if(b&1)r*=a; 18 return r; 19 } 20 int main(){ 21 int n; 22 scanf("%d",&n); 23 LL ans=1; 24 F(i,2,sqrt(n)){ 25 if(n%i==0){ 26 int k=0; 27 for(k;n%i==0;k++,n/=i); 28 ans*=(k+1)*Pow(i,k)-k*Pow(i,k-1); 29 // ans+=ans*(i-1)*k/i; 30 } 31 } 32 if (n!=1) ans*=2*Pow(n,1)-1; 33 printf("%lld\n",ans); 34 return 0; 35 }
【推荐】FlashTable:表单开发界的极速跑车,让你的开发效率一路狂飙
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 领域模型应用
· 记一次 ADL 导致的 C++ 代码编译错误
· MySQL查询执行顺序:一张图看懂SQL是如何工作的
· 为什么PostgreSQL不自动缓存执行计划?
· 于是转身独立开发者
· Cursor 1.2重磅更新,这个痛点终于被解决了!
· C#/.NET/.NET Core优秀项目和框架2025年6月简报
· 从被喷“假开源”到登顶 GitHub 热榜,这个开源项目上演王者归来!
· C#开发的Panel滚动分页控件(滑动版) - 开源研究系列文章
· 上周热点回顾(6.30-7.6)