欧拉筛法

本文介绍了欧拉筛法的时间复杂度和如何使用它解决积性函数问题,如欧拉函数、莫比乌斯函数、乘法逆元、最大公约数等,并给出了相关题目的例子和实现技巧,包括节省空间的策略和通用模板。

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

一. 筛法

例题:codevs1430

1. 埃拉托斯特尼筛法
vis[1]=1;
for (int i=2;i<=n;i++)
    if (!vis[i])
    {
        pri[++tot]=i;
        for (int j=i*2;j<=n;j+=i)
            vis[j]=1;
    }

时间复杂度:O(nloglogn)

2. 欧拉筛法

写法:

vis[1]=1;
for (int i=2;i<=n;i++)
{
    if (!vis[i])
        pri[++tot]=i;
    for (int j=1;j<=tot;j++)
    {
        if (i*pri[j]>n) break;
        vis[i*pri[j]]=1;
        if (i%pri[j]==0) break;
    }
}

时间复杂度:O(n)
证:每个和数被最小的质因子筛去

二. 欧拉筛法解积性函数

1. 方法

步骤Ⅰ:证明积性
步骤Ⅱ:考虑下面三方面的实现:
①素数m,求f(m)
②m和比m的最小素因子小的素数n,求f(n*m)
③m和m的最小素因子n:求f(n*m)

2. 例子
(1)欧拉函数

题目:PC 1499

证明:设n=apiim=bqii,且gcd(m,n)=1
ϕ(mn)=mn(11ai)(11bi)=[n(11ai)][m((11bi)]=ϕ(n)ϕ(m)

写法:
①素数m:ϕ(m)=m1
②m和比m的最小素因子小的素数n:
ϕ(mn)=ϕ(m)phi(n)
③m和m的最小素因子n:ϕ(mn)=ϕ(m)n

phi[1]=1;
for (int i=2;i<=n;i++)
{
    if (!phi[i])
    {
        pri[++tot]=i;
        phi[i]=i-1;
    }
    for (int j=1;j<=tot;j++)
    {
        if (i*pri[j]>n) break;
        if (i%pri[j]!=0)
            phi[i*pri[j]]=phi[i]*phi[pri[j]];
        else
        {
            phi[i*pri[j]]=phi[i]*pri[j];
            break;
        }
    }
}
(2)莫比乌斯函数

题目:PC 1492

积性证明:
n=apiim=bqii,且gcd(m,n)=1
①若pi>1qi>1,则μ(nm)=μ(n)μ(m)=0
②否则,μ(nm)=(1)n+m=μ(n)μ(m)
综上,μ(nm)=μ(n)μ(m)

写法:
①素数m:μ(m)=1
②m和比m的最小素因子小的素数n:
μ(mn)=μ(m)μ(n)
③m和m的最小素因子n:μ(nm)=0

mu[1]=vis[1]=1;
for (int i=2;i<=n;i++)
{
    if (!vis[i])
    {
        mu[i]=-1;
        pri[++tot]=i;
    }
    for (int j=1;j<=tot;j++)
    {
        if (i*pri[j]>n) break;
        vis[i*pri[j]]=1;
        if (i%pri[j]!=0)
            mu[i*pri[j]]=mu[i]*mu[pri[j]];
        else
        {
            mu[i*pri[j]]=0;
            break;
        }
    }
}
(3) 乘法逆元inv(n,i)(n不变)

题目:PC 1494

积性证明:
ainv[a]1,binv[b]1(modn)
(ab)(inv[a]inv[b])1(modn)
inv[ab]inv[a]inv[b]

写法:
①素数m:根据费马小定理,inv[m]Pow(m,n2)
②m和比m的最小素因子小的素数n:inv[mn]=inv[m]inv[n]
③m和m的最小质因子n:
根据完全积性,inv[mn]=inv[m]inv[n]

注意,第①步是O(n)的。这是因为:
O(π(n)logn)=O(nlnnlogn)=O(nlognlogn)=O(n)

vis[1]=inv[1]=1;
for (int i=2;i<n;i++)
{
    if (!vis[i])
    {
        pri[++tot]=i;
        inv[i]=Pow(i,n-2);
    }
    for (int j=1;j<=tot;j++)
    {
        if (i*pri[j]>n) break;
        vis[i*pri[j]]=1;
        inv[i*pri[j]]=inv[i]*inv[pri[j]];
        if (i%pri[j]==0) break;
    }
}

其实可以直接有一种递推的方法:
①当n=1时,inv[n]=1
②假设当前对于k,已经求出了inv[1],inv[2],…,inv[k-1],当前要求出inv[k]。
a=nmodkb=n/k
n=a+bk
a=nbk
inv[a]ainv[a](nbk)inv[a]bk1
inv[k]=binv[a]

(4)最大公约数gcd(a,b)(b一定)

题目:PC 1495

证明:略

写法:求g(i)
①素数m:g(m)=gcd(m,b)
②m和比m的最小素因子小的素数n:
g(mn)=g(m)g(n)
③m和m的最小质因子n:
ek(m)表示n的最大的幂,满足ek(m)|m
(ek(m)n)|b,则g(mn)=g(m)n
若不满足,则g(mn)=g(m)

ek(i)不是积性函数,但也可以放在欧拉筛法里面求:
①素数m:ek(m)=m
②m和比m的最小素因子小的素数n:ek(mn)=n
③m和m的最小质因子n:ek(mn)=ek(m)n

(5)正因子数目d(n)

题目:PC 1496

证明:
m=apiin=bqiim,n互质
d(mn)=d(apiibqii)=(pi1)(qi1)=d(m)d(n)

求法:求d(i)
①素数m:d(m)=2
②m和比m的最小素因子小的素数n:d(mn)=d(m)d(n)
③m和m的最小质因子n:
d(mn)=d(m)/(e(m)+1)(e(mm)+1)e(m)表示最大的满足ne(m)|m的值。

e(i)
①素数m:e(m)=1
②m和比m的最小素因子小的素数n:e(mn)=1
③m和m的最小质因子n:e(mn)=e(m)+1

(6)正因子之和s(n)

题目:PC 1497

证明:
m=apiin=bqiim,n互质,
s(mn)=j(pij=0aji)j(qij=0bji)=s(m)s(n)

写法:
①素数m:s(m)=m+1
②m和比m的最小素因子小的素数n:s(mn)=s(m)s(n)
③m和最小质因数n:
s(mn)=s(apiine(i)+1)=(pij=0aji)(e(i)+1j=0nj)=s(m)(e(i)+1j=0nj)(e(i)j=0nj)=s(m)ne(i)+21n1n1ne(i)+11=s(m)ne(i)+21ne(i)+11

pe(m)=ne(i)+1,则可以在欧拉筛法的同时求出。

(8)另一些显而易见的积性函数

1(n):1(n)=1,完全积性
Id(n):Id(n)=n,完全积性
Idk(n):Idk(n)=n^k,完全积性

3. 实现技巧
(1)节省空间

很多时候,有些数组A可以当作另外一些数组B的功能拓展,这时候就可以把B省略掉。

例如,在求欧拉函数的时候,我们可以用phi来取代vis数组。因为没有求出来的phi(i)也就意味着i是素数。

又例如,在求莫比乌斯函数的时候,我们可以用mu来取代vis数组。理由同上。不过要把mu数组的初始值设为-1。

(2)模板

变量:

  • 布尔数组vis[N]
  • 素数表pri[N],tot
  • 积性函数

模板:

void solve(void)
{
    vis[1]=...=1;   //赋初始值 
    for (int i=2;i<=n;i++)
    {
        if (!vis[i])
        {
            ...             //素数的积性函数值
            pri[++tot]=i;   //加入素数表 
        }
        for (int j=1;j<=tot;j++)
        {
            if (i*pri[j]>n) break;
            vis[i*pri[j]]=1;
            ...                 //公共部分
            if (i%pri[j]!=0)
            {
                ...             //m和比m的最小素因子小的素数n的处理 
            }
            else
            {
                ...             //m和m的最小素因子n的处理 
                break;
            }
        } 
    } 
}
4. 变式
(1)“加性”函数

例题:PC 1498
有些涉及到素因子的函数,也可以使用欧拉筛法求解。很多时候可以辅助积性函数的求解,上面的例子中的e函数,ek函数就是所谓的“加性”函数。

(2)A2

例题:XSY 1001
对于A2的积性函数,关键求出A的积性函数,然后顺便求解A2的积性函数。

(3)(A+1)(A1)

例题:XSY 1001
通常一个乘积的形式,也可以通过互质的关系,转化为有关积性函数的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值