求一個數的質因子以及尤拉函式
阿新 • • 發佈:2019-01-07
求一個數的質因子
程式碼:
#include<stdio.h> int main() { long long a[100],num,i,n; while(~scanf("%I64d",&n)) { num=0; for(i=2; i*i<=n; i++) { if(n%i==0) a[num++]=i; while(n%i==0) n/=i; } if(n>1) a[num++]=n; for(i=0; i<num; i++) printf("%I64d ",a[i]); printf("\n"); } return 0; }
第二個是我直接篩法寫的,但是這樣子的時間複雜度好像有點高,#include<stdio.h> #include<string.h> long long a[1000000]; int main() { long long i,j,n; scanf("%I64d",&n); memset(a,0,sizeof(a)); for(i=2; i<100000; i++) if(!a[i]) for(j=2*i; j<=n; j+=i) a[j]=1; for(i=2; i<=n; i++) { if(!a[i]&&n%i==0) printf("%I64d ",i); } return 0; }
定理:
算術基本定理,又稱為正整數的唯一分解定理,即:每個大於1的自然數均可寫為質數的積,而且這些素因子按大小排列之後,寫法僅有一種方式。例如:
算術基本定理的內容由兩部分構成:
分解的存在性;
分解的唯一性,即若不考慮排列的順序,正整數分解為素數乘積的方式是唯一的。
看過百度後感覺是好了一點,下面該尤拉函數了。
尤拉函式,就是求出不大於n且與n互素的數的個數
程式碼:
這個其實就是求一個數的質因數的變形(只不過是加了一點內容)就是尤拉函式的一個公式。#include<stdio.h> #include<math.h> int main() { int n,i,m; while(~scanf("%d",&n)) { if(n==1) printf("0\n"); else { m=sqrt(n+0.5); int ans=n; for(i=2; i<=m; i++) if(n%i==0) { ans=ans/i*(i-1); while(n%i==0) n/=i; } if(n>1) ans=ans/n*(n-1); printf("%d\n",ans); } } return 0; }
公式:
利用尤拉函式和它本身不同質因數的關係,用篩法計算出某個範圍內所有數的尤拉函式值。 尤拉函式和它本身不同質因數的關係: 尤拉函式ψ(N)=N{∏p|N}(1-1/p) 亦即: (P是數N的質因數) 直接代入公式就好了,對了,這一點,它還使用了一個開方向下取整的小細節,請教大神,說在1e9內都是沒有問題的,這個我也沒有求證,以後求證過了再補,(m=sqrt(n+0.5))還有容斥原理,有時間再寫吧。