51nod1040 最大公约数之和

求$\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

 

posted @ 2018-02-28 16:45  Blue233333  阅读(114)  评论(0编辑  收藏  举报