费马小定理和欧拉定理

费马小定理和欧拉定理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)$$

相关文章
相关标签/搜索