zoukankan      html  css  js  c++  java
  • 费马小定理和欧拉定理

    费马小定理和欧拉定理

    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)=nprod^{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] ]

    欧拉函数是积性函数,由它的意义我们可以用乘法原理证明,同时显然可以知道这不是完全积性函数

    例如三个正整数10,2,5,我们可以算到(phi(10)=4)

    ((n,m)=1),则有

    [phi(nm)=phi(n)*phi(m) ]

    我们可以根据定义得到如果n为素数,则(phi(n)=n-1),这个东西反向也是成立的
    我们可以根据这些性质来写出欧拉函数的线性筛法
    代码如下:

    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))时计算速度会快很多

    欧拉心算

    给出一个正整数(n(n<=10^7)),求

    [sum_{i=1}^{n}sum_{j=1}^{n}phi({gcd(i,j)}) ]

    思路:

    显然我们暴力是过不了的我们要考虑(O(n))或者更高效的算法

    我们肯定要推式子,所以直接拿那个题目的式子来推

    其中

    [sum(n)=sum_{i=1}^{n}phi(i) ]

    img

    这样我们就可以推出原式为

    [2*sum^n_{d=1}{(phi(d)*sum(lfloor frac{n}{d} floor))}-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
    ",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}equivprod_{i=1}^{r}{p_i}(mod m) ]

    消去可得

    [a^requiv1(mod m) ]

    所以

    [a^{phi(m)}equiv1(mod m) ]

  • 相关阅读:
    POJ2376 Cleaning Shifts
    百度首页图标
    NOIP2016换教室
    CH3803扑克牌
    【POJ2723】Get Luffy Out
    【USACO13DEC】 最优挤奶
    【SP2916】Can you answer these queries V
    【线段树】各种模板集合
    【SCOI2013】摩托车交易
    【CF1174D】 Ehab and the Expected XOR Problem
  • 原文地址:https://www.cnblogs.com/ezoihy/p/9634393.html
Copyright © 2011-2022 走看看