首页 > 其他 > 详细

51nod1040 最大公约数之和

时间:2018-02-28 17:07:42      阅读:181      评论:0      收藏:0      [点我收藏+]

求$\sum_{i=1}^{n}(i,n)$。n<=1e9。

$\sum_{i=1}^{n}(i,n)=\sum_{d|n}d\sum_{i=1}^{n}[(i,n)=d]=\sum_{d|n}d\sum_{k=1}^{\frac{n}{d}}[(k,\frac{n}{d})=1]=\sum_{d|n}d\varphi(\frac{n}{d})=\sum_{d|n}\frac{n\varphi(d)}{d}$

枚举因子。搞定。

技术分享图片
 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 //#include<map>
 6 #include<math.h>
 7 //#include<time.h>
 8 //#include<complex>
 9 #include<algorithm>
10 using namespace std;
11 
12 int n;
13 int list[22],num[22],len=0;
14 
15 #define LL long long
16 LL ans;
17 void dfs(int cur,int now,int s)
18 {
19     if (cur>len)
20     {
21         int p=now;
22         for (int i=1;i<=len;i++) if ((s>>(i-1))&1) p=p/list[i]*(list[i]-1);
23         ans+=n/now*p; return;
24     }
25     dfs(cur+1,now,s);
26     for (int i=1,tmp=list[cur];i<=num[cur];i++,tmp*=list[cur]) dfs(cur+1,now*tmp,s|(1<<(cur-1)));
27 }
28 
29 int main()
30 {
31     scanf("%d",&n);
32     int tnt=n;
33     for (int i=2;1ll*i*i<=tnt;i++) if (tnt%i==0)
34     {
35         list[++len]=i;
36         while (tnt%i==0) tnt/=i,num[len]++;
37     }
38     if (tnt) {list[++len]=tnt; num[len]=1;}
39     ans=0; dfs(1,1,0); printf("%lld\n",ans);
40     return 0;
41 }
View Code

 

51nod1040 最大公约数之和

原文:https://www.cnblogs.com/Blue233333/p/8484466.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!