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;
    }
  • 相关阅读:
    (原创)神舟笔记本bios设置——神船战神ZX7-CP7S2 <一>
    Kali笔记<三> 安装中文输入法
    (原创)Kali笔记<二>root权限的使用和启用
    (原创)Kali笔记<一>虚拟机安装Kali
    加快vmware虚拟机运行速度的方法(大牛勿笑)
    PR/AE/PS 素材模板网站
    批量查杀该死的VBscript “svchost.exe” 脚本挂马
    echarts统计图Y轴(或X轴)文字过长问题解决
    正则实例
    Angular.js的自定义功能
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/14393325.html
Copyright © 2011-2022 走看看