歐拉降冪學習

例題鏈接:https://cn.vjudge.net/problem/FZU-1759

題目大意
A^B mod C,其中b是一個非常大的數,求其數值。

算法的實現過程:
歐拉函數是指:對於一個正整數n,小於n且和n互質的正整數(包括1)的個數,記作φ(n) 。

歐拉函數的公式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)……(1-1/pn); 其中p1, p2……pn爲x的所有質因數,且x是不爲0的整數。φ(1)=1(唯一和1互質的數就是1本身)。

注意:對於質數p,φ§ = p – 1。注意φ(1)=1.

歐拉定理:對於互質的正整數a和n,有aφ(n) ≡ 1 mod n。

歐拉函數是積性函數
若m,n互質,φ(mn)=φ(m)φ(n)

若n是質數p的k次冪,φ(n)=pk-p(k-1)=(p-1)p^(k-1),因爲除了p的倍數外,其他數都跟n互質。

特殊性質:當n爲奇數時,φ(2n)=φ(n)

歐拉函數還有這樣的性質:

設a爲N的質因數,若(N % a == 0 && (N / a) % a == 0) 則有E(N)=E(N / a) * a;若(N % a == 0 && (N / a) % a != 0) 則有:E(N) = E(N / a) * (a – 1)。

歐拉函數的實現:

ll ol(ll x){
    ll i,res=x;
    for(i=2;i*i<=x;i++){
        if(x%i==0){
            res=res-res/i;
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        res=res-res/x;
    return res;
}

歐拉降冪的公式:
在這裏插入圖片描述
代碼:

#include <iostream>
using namespace std;
#define ll long long
ll ol(ll x){
    ll i,res=x;
    for(i=2;i*i<=x;i++){
        if(x%i==0){
            res=res-res/i;
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        res=res-res/x;
    return res;
}
ll qpow(ll x,ll y,ll mod){
    ll res=1;
    while(y){
        if(y%2)
            res=res*x%mod;
        x=x*x%mod;
        y/=2;
    }
    return res;
}
int main()
{
    ll a,c,ans,oula,b;
    string s;
    while(cin>>a>>s>>c){
        ans=0;
        b=0;
        oula=ol(c);
        int l=s.size();
        for(int i=0;i<l;i++){
            char ss=s[i];
            b=(b*10+ss-'0')%oula;
        }
        b+=oula;
        ans=qpow(a,b,c);
        cout<<ans<<endl;
    }
    return 0;
}

參考博客:https://jhcloud.top/blog/?p=1758

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章