1. 程式人生 > >51nod level-5 系列

51nod level-5 系列

printf print F12 ace 求一個 sin 需要 style std

2017-8-15
技術分享

題目思路:滿足 gcd(x,n)==d 的x的數量即是 最大公約數d的貢獻度,
那麽 gcd(x,n)==d 的數量 等價於 gcd(x/d,n/d)==1的數量 , 即為歐拉函數
因此,我們枚舉n所有的因子i,求一個euler(n/i) 即為gcd==i的數量,
又由於這裏 n是1e9範圍 , 因子都是成對出現的 因此可以枚舉因子到根號n即可
若是兩個因子不相等,那麽兩個因子的貢獻度都要加上,相等只需要算一次
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
5 6 int n; 7 //int euler[100010]; 8 9 //void init(){ 10 // euler[1]=1; 11 // for(int i=2;i<100000;i++) 12 // euler[i]=i; 13 // for(int i=2;i<100000;i++) 14 // if(euler[i]==i) 15 // for(int j=i;j<100000;j+=i) 16 // euler[j]=euler[j]/i*(i-1);//先進行除法是為了防止中間數據的溢出 17 //} 18 19 //直接求解歐拉函數
20 int euler(int n){ //返回euler(n) 21 int res=n,a=n; 22 for(int i=2;i*i<=a;i++){ 23 if(a%i==0){ 24 res=res/i*(i-1);//先進行除法是為了防止中間數據的溢出 25 while(a%i==0) a/=i; 26 } 27 } 28 if(a>1) res=res/a*(a-1); 29 return res; 30 } 31 32 33 int main()
34 { 35 36 scanf("%d",&n); 37 LL ans=0; 38 for(int i=1;i*i<=n;i++) 39 { 40 if(n%i) continue; 41 int d=n/i; 42 ans=ans+1LL*euler(d)*i; 43 if(d!=i) ans=ans+1LL*euler(i)*d; 44 } 45 printf("%lld\n",ans); 46 }




51nod level-5 系列