zoukankan      html  css  js  c++  java
  • 数学知识-欧拉函数&快速幂

    欧拉函数

    定义

    对于正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目,记作φ(n).

     算法思路

    既然求解每个数的欧拉函数,都需要知道他的质因子,而不需要个数

    因此,我们只需求出他的质因子,然后根据公式:N*(p1-1)/p1*(p2-1)/p2......即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll n;
    
    int main()
    {
        ll i,j;
        cin>>n;
        for(i=0;i<n;i++)
        {
            ll x;
            cin>>x;
            ll ans=x;
            for(j=2;j<=x/j;j++)
            {
                if(x%j==0)
                {
                    ans=ans*(j-1)/j;
                    while(x%j==0)
                    {
                        x/=j;
                    }
                }
            }
            if(x!=1)
                ans=ans*(x-1)/x;
            cout<<ans<<endl;
        }
        return 0;
    }

    筛法求欧拉函数

    问题

    给定一个正整数n,求1~n中每个数的欧拉函数之和。

    算法思路

    使用线性筛的方法,来求每个数的欧拉函数

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+10;
    int n,cnt;
    bool st[N];
    int primes[N];
    int phi[N];
    
    
    void get_eulers()
    {
        int i,j;
        phi[1]=1;
        for(i=2;i<=n;i++)
        {
            if(!st[i])
            {
                primes[cnt++]=i;
                phi[i]=i-1;
                for(j=0;primes[j]<=n/i;j++)
                {
                    st[primes[j]*i]=true;
                    if(i%primes[j]==0)
                        phi[primes[j]*i]=primes[j]*phi[i];
                    else
                        phi[primes[j]*i]=(primes[j]-1)*phi[i];
                }
            }
        }
        int ans=0;
        for(i=1;i<=n;i++)
            ans+=phi[i];
        cout<<ans<<endl;
    }
    
    int main()
    {
        int i,j;
        cin>>n;
    
        get_eulers();
    
        return 0;
    }

    快速幂

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    void suppow(ll a,ll b,ll p)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
                ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        cout<<ans%p<<endl;
    }
    
    int main()
    {
        ll n,a,b,p;
        cin>>n;
        while(n--)
        {
            cin>>a>>b>>p;
            suppow(a,b,p);
        }
    
    
        return 0;
    }

    快速幂求逆元

    前提

     代码

    快速幂求解:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    
    ll supow(ll a,ll b,ll p)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
                ans=ans*a%p;
            a=a*a%p;
            b>>=1;
        }
        return ans;
    }
    
    int main()
    {
        ll a,p,n;
        cin>>n;
        while(n--)
        {
            cin>>a>>p;
            if(a%p!=0)
            {
                cout<<supow(a,p-2,p)<<endl;
            }
            else
                puts("impossible");
        }
        return 0;
    }

    扩展欧几里得求逆元

    #include <iostream>
    using namespace std;
    typedef long long LL;
    int n;
    
    int exgcd(int a, int b, int &x, int &y)
    {
        if (!b) {
            x = 1, y = 0;
            return a;
        }
        int d = exgcd(b, a % b, y, x);
        y -= a / b * x;
        return d;
    }
    
    
    int main()
    {
        cin >> n;
        while (n --)
        {
            int a, p, x, y;
            // if (a < p) swap(a, p);
            cin >>  a >> p;
            int d = exgcd(a, p, x, y);
            if (d == 1) cout << ((LL)x + p) % p << endl;//保证x是正数
            else puts("impossible");
    
        }
        return 0;
    }
  • 相关阅读:
    算法分析(3)——冒泡排序真的慢吗?
    算法分析(2)——大O和大Θ
    算法分析(1)——数据的影响和函数的增长
    递归的逻辑(5)——米诺斯的迷宫
    递归的逻辑(4)——递归与分形
    李洪强和你一起学习前端之(9)规避脱标,CSS可见性,滑动门案例
    iOS应用管理(优化)
    iOS开发-应用管理
    iOS开发-Tom猫
    iOS 10.3.3 更新背后的故事
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/14393325.html
Copyright © 2011-2022 走看看