zoukankan      html  css  js  c++  java
  • 欧拉函数及其性质

    欧拉函数

    定义:欧拉函数指对于以正整数n,phi[n]=1~n(不包括n)中与n互质的正整数的个数。

    下面给出求解欧拉函数的两种方法:直接求解和打表法;

    //直接求解欧拉函数,基于容斥定理
    int phi(int n){ 
         int res=n;
         for(int i=2;i*i<=n;i++){
             if(n%i==0){
                 res=res/i*(i-1);       //先进行除法是为了防止中间数据的溢出 
                 while(n%i==0) n/=i;
             }
         }
         if(n>1) res=res/n*(n-1);
         return res;
    }
    
    #define maxn 1000001
    int phi[maxn];
    void Init()             //打表求一个区间内所有的欧拉函数值
    { 
         phi[1]=1;
         for(int i=2;i<maxn;i++)
           phi[i]=i;
         for(int i=2;i<maxn;i++)
            if(phi[i]==i)
               for(int j=i;j<maxn;j+=i)
                  phi[j]=phi[j]/i*(i-1);    //先进行除法是为了防止中间数据的溢出 
    }
    

    欧拉函数性质

    欧拉函数性质:

    1:若p是素数,则(phi(p)=p-1)

    2:对于两个素数,(phi(p*q)=p*q-1)

    3:对于(m=n^k),(phi(m)=phi(n^k)=n^k-n^{k-1});

    欧拉定理:

    [当a与m互质时有: a^{φ(m)} ≡ 1(mod m) ]

    扩展欧拉定理:

    [当b >= φ(m)时有: a^b ≡ a^{(b\%φ(m)+φ(m))}(mod m) ]

    一道扩展欧拉的应用题:给你三个正整数a, m, b,你需要求:(a^b\% m),范围a:(10^9), m:(10^8), b:(10^{20000000})。直接扩展欧拉定理即可,对b边读边取模, 再特判一下b与phi(m)的大小即可。

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5 + 10;
    const int inf = 0x3f3f3f3f;
    int gcd(int a,int b)    { return b == 0 ? a : gcd(b, a % b); }
    
    LL a, m, mod;
    string b;
    LL phi(LL n){ 
         LL res = n;
         for(int i = 2;i * i <= n; i++){
             if(n % i == 0){
                 res = res / i * (i - 1);       //先进行除法是为了防止中间数据的溢出 
                 while(n % i == 0) n /= i;
             }
         }
         if(n > 1) res = res / n * (n - 1);
         return res;
    }
    LL qpow(LL a, LL k, LL mod){
        LL ans = 1 % mod;
        while(k){
            if(k & 1)   ans = ans * a % mod;
            k >>= 1;
            a = a * a % mod;
        }
        return ans;
    }
    
    int main()
    {
        cin >> a >> m;
        cin >> b;
        mod = phi(m);
        int ans = 0, len = b.length(), ok = 0;
        for(int i = 0; i < len; ++i){
            ans = ans * 10;
            ans = ans + b[i] - '0';
            if(ans >= mod)  ok = 1;
            ans %= mod;
        }
        b = ans % mod + mod;
        if(!ok) b -= mod;	//如果ans(及b mod phi(m))是小于b的,那么不能用扩展欧拉, 这是直接算a^b即可
        cout << qpow(a, b, m) << endl;
        system("pause");
    }
    
  • 相关阅读:
    Python基本数据类型(int str)个人笔记
    LINUX简单操作的笔记
    samba服务配置步骤
    IP地址的初步理解
    apache服务配置步骤
    [已解决]This dependency was not found: * common/stylus/index.styl in ./src/main.js To install it, you can run: npm install --save common/stylus/index.styl
    (转)iFrame高度自适应
    (转)Div左右两侧等高
    (转)Css样式兼容IE6,IE7,FIREFOX的写法
    瀑布流布局代码
  • 原文地址:https://www.cnblogs.com/StungYep/p/12252411.html
Copyright © 2011-2022 走看看