欧拉函数,欧拉定理,费马定理

欧拉函数:指从1-n中与n互质的数的个数

首先要知道,一个数 $n$ 分解质因数之后会变成这样一个形式:

$n$ = $p1k1$ + $p2k2$+ ... + $pnkn$

而欧拉函数: $φ$= $n$ * (1-1/p1) * (1-1/p2) * ... * (1-1/pn).

证明: 

1. 由于n可以被分解为p1,p2..的倍数,那么首先要用 n-n/p1-n/p2-...

2. 加上pi*pj的倍数,因为这当中有被重复减去的数,要加回去

3. 加上pi*pj*pk的倍数,因为有可能三个数的倍数被减去

4.....依次类推

 

 朴素做法:

 

//欧拉函数:1-n当中与n互质的数的个数
#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10,mod=1e9+7;
string s;
int n,t,a[N],f[N],res,num,ans;
bool vis[N];
int main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        res=n;
        for(int i=2;i<=n/i;i++){
            if(n%i==0){
                //res=res*(1-1/i);
                res=res/i*(i-1);//和上面的公式一样的,只是相除有可能因为浮点数影响判断
                while(n%i==0) n/=i;
            }
        }
        if(n>1) res=res/n*(n-1);
        cout<<res<<endl;
    }
    return 0;
}

欧拉筛法求欧拉函数:

 

#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10,mod=1e9+7;
string s;
long long  n,t,a[N],f[N],res,num,ans,prime[N];
bool vis[N];
long long get_ouler(int u)
{
    res=0,f[1]=1;
    for(int i=2;i<=u;i++){
        if(!vis[i]){
            prime[++num]=i;
            f[i]=i-1;//如果是质数,那么它与他互质的个数就是i-1
        }
        for(int j=1;prime[j]<=n/i;j++){
            vis[prime[j]*i]=true;
            if(!(i%prime[j])){  
                f[prime[j]*i]=f[i]*prime[j];
                break;
            }
            f[prime[j]*i]=f[i]*(prime[j]-1);
        }
    }
    for(int i=1;i<=n;i++) res+=f[i];
    return res;
}
int main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n;
    cout<<get_ouler(n)<<endl;
    return 0;
}

 

欧拉定理:

若a与n互质,则  aφ(n)%n≡1也就是a的欧拉函数的n次方模n同余与1

费马定理:   当n是质数的时候: an-1%n≡1

 

posted @ 2023-06-21 14:05  o-Sakurajimamai-o  阅读(51)  评论(0)    收藏  举报
-- --