1. 程式人生 > >51nod1040 最大公約數之和

51nod1040 最大公約數之和

include std phi isp opened one 51nod play 分享圖片

求$\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 最大公約數之和