1. 程式人生 > >約數定理(約數個數定理,約束和定理)

約數定理(約數個數定理,約束和定理)

約數個數定理:

對於一個大於1正整數n可以分解質因數 則n的正約數的個數就是 其中a1、a2、a3…ak是p1、p2、p3,…pk的指數。

定理簡證:

首先同上,n可以分解質因數:n=p1^a1×p2^a2×p3^a3*…*pk^ak, 由約數定義可知p1^a1的約數有:p1^0, p1^1, p1^2......p1^a1 ,共(a1+1)個;同理p2^a2的約數有(a2+1)個......pk^ak的約數有(ak+1)個。 故根據乘法原理:n的約數的個數就是(a1+1)(a2+1)(a3+1)…(ak+1)。

例題:

例題:正整數378000共有多少個正約數
? 解:將378000分解質因數378000=2^4×3^3×5^3×7^1 由約數個數定理可知378000共有正約數(4+1)×(3+1)×(3+1)×(1+1)=160個。

約數和定理:

對於一個大於1正整數n可以分解質因數:n=p1^a1*p2^a2*p3^a3*…*pk^ak, 則由約數個數定理可知n的正約數有(a₁+1)(a₂+1)(a₃+1)…(ak+1)個, 那麼n的(a₁+1)(a₂+1)(a₃+1)…(ak+1)個正約數的和為 f(n)=(p1^0+p1^1+p1^2+…p1^a1)(p2^0+p2^1+p2^2+…p2^a2)…(pk^0+pk^1+pk^2+…pk^ak)

定理證明:

證明:若n可以分解質因數:n=p1^a1*p2^a2*p3^a3*…*pk^ak, 可知p1^a1的約數有:p1^0, p1^1, p1^2......p1^a1 … 同理可知,pk^ak的約數有:pk^0, pk^1, pk^2......pk^ak ; 實際上n的約數是在p1^a1、p2^a2、...、pk^ak每一個的約數中分別挑一個相乘得來, 可知共有(a₁+1)(a₂+1)(a₃+1)…(ak+1)種挑法,即約數的個數。 由乘法原理可知它們的和為 f(n)=(p1^0+p1^1+p1^2+…p1^a1)(p2^0+p2^1+p2^2+…p2^a2)…(pk^0+pk^1+pk^2+…pk^ak)

例題:

例題:正整數360的所有正約數的和是多少? 解:將360分解質因數可得 360=2^3*3^2*5^1 由約數和定理可知,360所有正約數的和為 (2^0+2^1+2^2+2^3)×(3^0+3^1+3^2)×(5^0+5^1)=(1+2+4+8)(1+3+9)(1+5)=15×13×6=1170 可知360的約數有1、2、3、4、5、6、8、9、10、12、15、18、 20、24、30、36、40、45、60、72、90、120、180、360;則它們的和為 1+2+3+4+5+6+8+9+10+12+15+18+20+24+30+36+40+45+60+72+90+120+180+360=1170

所有因子個數τ(n)與所有因子的和σ(n)都是乘(積)性函式。

定義1:因子和函式σ定義為整數n的所有正因子之和,記為σ(n)。

定義2:因子個數函式τ定義為正整數n的所有正因子個數,記為τ(n)。

定理1:設p是一個素數,a是一個正整數,那麼

                                σ(n)=1+p+p^2+……+p^a=【p^(a+1)-1】/(p-1)

                                τ(n)=a+1

定理2:設正整數n有素因子分解 n =(p1^α1)*(p2^α2)*(p3^α3)* ....... *(pk^αk),那麼

             σ(n)=【(p1^α1)-1】/(p1-1) * 【(p2^α2)-1】/(p2-1) * .....  *【(pk^αk)-1】/(pk-1)

             τ(n)=(α1+1)*(α2+1)*(α3+1)*......*(αk+1)

求因子個數:
int prime[maxn],nprime;  
int vis[maxn];  
  
void getprime(){
    nprime = 0;
    memset(vis,0,sizeof(vis));
    for(int i = 2; i <= 450; i++){
        int t = 450/i;
        for(int j = 2; j <=t; j++)
            vis[i*j] = 1;
    }
    for(int i = 2; i <= 450; i++){
        if(!vis[i])
            prime[nprime++] = i;
    }
}
  
int factor_count(int n){  
    int ans = 1,sum;  
    int k = sqrt(n*1.0);  
    for(int i = 0; prime[i] < k; i++){  
        if(n % prime[i] == 0){  
            sum = 0;  
            while(n % prime[i] == 0){  
                sum++;  
                n /= prime[i];  
            }  
            ans *= (a+1);  
        }  
    }  
    if(n > 1)  
        ans *= 2;  
    return ans;  
}  



求因子和:
int prime[maxn],nprime;
int vis[maxn];

void getprime(){
    nprime = 0;
    memset(vis,0,sizeof(vis));
    for(int i = 2; i <= 450; i++){
        int t = 450/i;
        for(int j = 2; j <=t; j++)
            vis[i*j] = 1;
    }
    for(int i = 2; i <= 450; i++){
        if(!vis[i])
            prime[nprime++] = i;
    }
}

int pow_mod(int a,int n,int MOD){
    int ans = 1;
    while(n){
        if(n&1)
            ans = (ans*a)%MOD;
        n >>= 1;
        a = (a*a)%MOD;
    }
    return ans;
}

int factor_sum(int n){
    int ans = 1,sum;
    int k = sqrt(n*1.0);
    for(int i = 0; prime[i] < k; i++){
        if(n % prime[i] == 0){
            sum = 0;
            while(n%prime[i] == 0){
                sum++;
                n /= prime[i];
            }
            ans *= (pow_mod(prime[i],sum+1,MOD)-1)/(prime[i]-1);
        }
    }
    if(n > 1)
        ans *= ans(n*n-1)/(n-1);
    return ans;
}