基础数论算法(7) 欧拉函数与BSGS算法

本文介绍了数论中的欧拉函数概念及其计算方法,并详细解释了如何利用积性函数特性进行高效计算。同时,文章还探讨了BSGS算法的工作原理及应用,用于解决特定的模指数方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

欧拉函数

我真的觉得欧拉无所不能…


在提到欧拉函数之前,我们先要说一个定义:积性函数。什么是积性函数?对于互质的数a,b,有f(ab)=f(a)*f(b)。
这个玩意真的特别神奇。最简单的积性函数是τ(n),这个函数表示所有因子数量。例如,τ(6)=4τ(2)=2τ(3)=2τ(6)=τ(2)τ(2)
另一个积性函数是σ(n)表示所有因子之和。σ(6)=12σ(2)=3σ(3)=4σ(6)=σ(2)σ(3)
欧拉函数是什么呢?我们称1~n中与n互质的数的个数为欧拉函数,记作ϕ(n)。作为积性函数,我们还是用6来验证一下:ϕ(6)=2ϕ(2)=1ϕ(3)=2ϕ(6)=ϕ(2)ϕ(3)。是不是觉得非常神奇?
那么如何求欧拉函数值?有这样一个公式:

ϕ(n)=n(11pi)pin

例如,160=255,所以ϕ(160)=1601245=64。那这个东西怎么得来的呢?

以下内容大可无视
来考虑假设p是a的一个因数
那么ap就是1~a中所有的p的倍数的个数
因此不妨来考虑一下这样一个概率问题:从1~a中选出一个数与a互质
这就是一个古典概型,假定a=pk11pk22...pknn,那么显然p1,p2,...,pn的倍数都是与a不互质的。
因此,这就是一个分步的乘法原理:拿到非pi的倍数的概率为11pi,结果相乘。
所以,拿到与p互质的数的概率就是(11pi)
因此,ϕ(n)=n(11pi)pin

这样我们可以在O(n)的时间内求出某个数的欧拉函数值。如果用一些高科技手段分解质因数,又会略微快一点。
但是一般来说如果要涉及到欧拉函数都是多组的,那么这样求出一个欧拉函数表复杂度要O(n2)。这是我们不能容忍的,所以我们可以在欧拉筛里加几句话来处理出一张欧拉函数表。
首先,我们需要了解几个东西。
(1)对素数来说,ϕ(n)=n1
(2)如果p为质数,i mod p0,那么
ϕ(ip)=ϕ(i)ϕ(p)=ϕ(i)(p1)
(3)如果p为质数,i mod p=0,那么ϕ(ip)=pϕ(i)
前两条都是显然的,一个是素数本身的性质,一个是积性函数的定义。第三条比较有趣,我们来看一下之前得到的公式:
ϕ(i)=i(11pj)pji,观察一下就会发现,这里由于p为i的质因数,所以(11pi)这一部分并未发生改变,亦即ϕ(np)=pn(11pi)=pϕ(n).

那么接下来就是欧拉函数与欧拉筛相结合。代码:

#include <iostream>
#define MAXN 40003
using namespace std;
int n;
int phi[MAXN],prime[MAXN],cnt,ans;
bool notprime[MAXN];
void getphi(){
    int i,j;
    phi[1]=1;
    for(i=2;i<=40000;++i){
        if(!notprime[i]){
            prime[++cnt]=i;
            phi[i]=i-1;
        }
        for(j=1;j<=cnt;++j){
            if(i*prime[j]>0) break;
            notprime[i*prime[j]]=1;
            if(i%prime[j]==0){
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }else{
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
}
int main(){
    getphi();
    return 0;
}

非常有趣吧。


北上广深 拔山盖世 BSGS算法

北上广深,啊不对,BSGS算法是Baby-step-Giant-step的简称,从名字上看就是挺蛋疼的一个算法。BSGS算法的用处在于,求解AxB(mod  C)其中C为素数。不过相对应的还有EXBSGS用于解C不为素数的情况,那就比较复杂了我们不谈它。
因为一般而言NOIP考数论都会放在Day2的T1,所以出这玩意概率并不大……总之了解一下吧。

AxB(mod C)
m=m ,x=im+j
(Ai)mAjB(mod C)
AjB(Ai)m(mod C)
是不是看到了什么熟悉的东西?没错,exgcd求逆元。
我们先将Aj存在Hash表中,然后枚举i,快速的查出结果。
Aj存表我们称为Baby Step,而枚举i我们称为Giant Step.

代码我就不抄了……各位自己去搜吧,主要把思想了解一下就可以了qwq


那么数论专题基本上没剩什么了,接下来大概是处理一下矩阵快速幂优化求某一类数列的值以及高斯消元法求解线性方程组,还有Catalan数的相关知识。虽然不能算得上是数论,不过放到一块算了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值