費馬小定理和歐拉定理

費馬小定理和歐拉定理ios

1.費馬小定理

1)定義

咱們如今設正整數$a,m$且$m$是素數 咱們就會有式子 $$a^{m-1}\equiv1(mod\ m)$$算法

2)證實

咱們設一個徹底剩餘系$A={1,2,3,...,m-1}$ 又由於$(a,m)=1$ 咱們又獲得另外一個徹底剩餘系$B={1a,2a,3a,...,(m-1)a}$,這裏其實就是一個餘數的可乘性的運用 根據徹底剩餘系的性質咱們 $$(m-1)!\equiv(m-1)!*a^{m-1}(mod\ m)$$ 兩邊同時消去就可得 $$a^{m-1}\equiv1(mod\ m)$$函數

2.歐拉定理

1)歐拉函數

歐拉函數記爲$\phi$,且一般定義在正整數域上 比較直接點,歐拉函數通式是長這樣的 $$\phi(n)=n\prod^{x}{i=1}(1-\frac{1}{p_i})$$ 其中x爲n的質因數個數,而$p_i$是n的第i個質因數 其實歐拉函數更重要的意義是:$\phi(n)$表示小於等於n且與n互質的正整數的個數 由此咱們能夠的這麼一條僞通式 $$\phi(n)=\sum^{n}{i=1}[(n,i)==1]$$ 歐拉函數是積性函數,由它的意義咱們能夠用乘法原理證實,同時顯然能夠知道這不是徹底積性函數ui

例如三個正整數10,2,5,咱們能夠算到$\phi(10)=4$spa

若$(n,m)=1$,則有 $$\phi(nm)=\phi(n)*\phi(m)$$ 咱們能夠根據定義獲得若是n爲素數,則$\phi(n)=n-1$,這個東西反向也是成立的 咱們能夠根據這些性質來寫出歐拉函數的線性篩法 代碼以下:code

void getEuler(int x){
    eul[1]=1;
    for(int i=2;i<=x;i++){
        if(!eul[i]){
            pri[++tot]=i;
            eul[i]=i-1;
        }
        for(int j=1;j<=tot and i*pri[j]<=x;j++){
                if(!(i%pri[j])){
                    eul[i*pri[j]]=eul[i]*pri[j];
                    break;
                }
                eul[i*pri[j]]=eul[i]*(pri[j]-1);
            }
    }
}

歐拉函數在信息學競賽中使用的仍是蠻多的,固然在解決實際數學問題中歐拉函數也是一個極其有用的東西,例如咱們在求${17}^{2017}\equiv x(mod\ 23)$時計算速度會快不少blog

歐拉心算

給出一個正整數$n(n<=10^7)$,求 $$\sum_{i=1}^{n}\sum_{j=1}^{n}\phi({gcd(i,j)})$$get

思路:

顯然咱們暴力是過不了的咱們要考慮$O(n)$或者更高效的算法數學

咱們確定要推式子,因此直接拿那個題目的式子來推string

其中

$$sum(n)=\sum_{i=1}^{n}\phi(i)$$

img

這樣咱們就能夠推出原式爲

$$2*\sum^n_{d=1}{(\phi(d)*sum(\lfloor \frac{n}{d} \rfloor))}-sum(n)$$

因此咱們能夠用線性篩篩出歐拉函數而後咱們再求一次前綴和

代碼:

#include<iostream>
#include<cstring>
#include<cstdio>
  
using namespace std;
  
int tot,n,pri[10000001];
long long eul[10000001];
 
inline int rd(){
    register int x=0,y=1;register char c=getchar();
    while(c<'0' or c>'9'){
        if(c=='-')y=-1;
        c=getchar();
    }
    while(c>='0' and c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x*y;
}
 
void getEuler(int x){
    eul[1]=1;
    for(int i=2;i<=x;i++){
        if(!eul[i]){
            pri[++tot]=i;
            eul[i]=i-1;
        }
        for(int j=1;j<=tot and i*pri[j]<=x;j++){
                if(!(i%pri[j])){
                    eul[i*pri[j]]=eul[i]*pri[j];
                    break;
                }
                eul[i*pri[j]]=eul[i]*(pri[j]-1);
            }
    }
    for(int i=2;i<=x;i++)eul[i]+=eul[i-1];
}
  
long long solve(int x){
    long long ret=0;int nxt;
    for(int i=1;i<=x;i=nxt+1){
        nxt=x/(x/i);
        ret+=(eul[nxt]-eul[i-1])*eul[x/i]*2-(eul[nxt]-eul[i-1]);
    }
    return ret;
}
  
int main(){
    n=rd();
    getEuler(10000000);
    while(n--){
        int x=rd();
        printf("%lld\n",solve(x));
    }
    return 0;
}

2)定義

如今咱們來引入歐拉定理,實際上歐拉定理就是費馬小定理的推廣在m爲素數時顯然就是費馬小定理 咱們先定義兩個互質的正整數$a,m$ 咱們就會有 $$a^{\phi(m)}\equiv1(mod \ m)$$

3)證實

咱們令$r=\phi(n)$ 咱們先設一個有$r$個元素的集合$P={p_1,p_2,p_3,...p_r}$,其中$p_i$是第i個與m互質的數 又由於$(a,m)=1$,且P集合中的全部元素都與m互質,因此集合$P'={ap_1,ap_2,ap_3,...ap_r}$的全部元素都與m互質,且屬於模m的r個不一樣的剩餘類$[p_1],[p_2],..[p_r]$,這裏咱們用同餘的性質很容易就能夠想到 $$a^r*\prod_{i=1}^{r}{p_i}\equiv\prod_{i=1}^{r}{p_i}(mod \ m)$$ 消去可得 $$a^r\equiv1(mod\ m)$$ 因此 $$a^{\phi(m)}\equiv1(mod\ m)$$

相關文章
相關標籤/搜索