1. 程式人生 > >求一個數的質因子以及尤拉函式

求一個數的質因子以及尤拉函式

求一個數的質因子

程式碼:

#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))還有容斥原理,有時間再寫吧。