欧拉函数+欧拉降幂

前言:不知道为什么,最近几场比赛都是数学场,整的我和自闭儿一样......

昨天牛客的比赛有一个关于欧拉降幂的题,因为是知识盲区再加上喝了假酒,于是寄。


正文:

在学欧拉降幂之前要知道什么是欧拉函数。

在数论,对正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目(φ(1)=1)。

求欧拉函数的两个方法

方法一:线性求解

前置定理:

如果 i%p==0 ,其中 p 为质数,则 \varphi (i*p)=\varphi (i)*p,否则\varphi (i*p)=\varphi (i)*(p-1)

线性求解只用在欧拉筛上加一点东西就行,代码如下:

    vector<int>phi(2e5+1);
    phi[1] = 1;//初始化
    vector<int>primes(2e5+1);
    function<void()>prepare=[&](){
        int j=-1;
        for(int i = 2; i <= 2e5; i++){
            if(primes[i]==0){
                primes[++j]=i;
                phi[i]=i-1;
            }
            for(int t = 0;t <= j && primes[t]*i <= 2e5; t++){
                primes[i * primes[t]] = 1;
                if(i % primes[t] == 0){
                    phi[i*primes[t]] = primes[t]*phi[i];
                    break;
                }
                else phi[i*primes[t]] = (primes[t] - 1)*phi[i];
            }
        }
    };

方法二:sqrt(n) 单点求解

前置定理:

若 n=p_{1}^{k_{1}}p_{2}^{k_{2}}p_{3}^{k_{3}}...p_{m}^{k_{m}},其中p为质数,则\varphi (n) = n*\prod_{i=1}^{m}(1-\frac{1}{p_{i}})

代码如下:

    function<void(ll)>getphi=[&](ll x){
        ll ans=x;
        for(int i = 2;i*i <= x;i++){
            if(x % i == 0){
                ans = ans - ans / i;
                while(x % i == 0) x /= i;
            }
        }
        if(x != 1)ans = ans - ans/x;
        return ans;
    };

欧拉降幂

关于欧拉降幂,主要要记住这么几个结论(这里就不证明了,以前我尝试证明每一个数学结论,然后发现当时明白了,过几天又忘,还整的自己生不如死

公式一

若  gcd(a,mod)=1

a^{b}%mod=a^{b%\varphi (mod)}%mod

公式二:

若 gcd(a,mod) \neq 1 且 b>=\varphi (mod)

a^{b}%mod=a^{b%\varphi (mod)+\varphi (mod)}%mod

公式三:

若 gcd(a,mod)\neq 1 且 b<\varphi (mod)

a^{b}%mod=a^{b}%mod

后记:

在学欧拉降幂的时候,我突然发现我的快速幂的写法是有问题的。

原来的快速幂板子:


ll ksm(ll a,ll b){
    ll kase = 1 ;
    while(b){
        if(b&1){
            kase = kase * a %mod;
        }
        a = a*a %mod;
        b>>=1;
    }
    return kase ;
}

 这样写会出现这样的情况,当mod=1,b=0,的时候,输出的不是0。

解决方案:


ll ksm(ll a,ll b){
    ll kase = 1 ;
    while(b){
        if(b&1){
            kase = kase * a %mod;
        }
        a = a*a %mod;
        b>>=1;
    }
    return kase%mod ;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值