线性筛求积性函数
线性筛求积性函数
(更新中)
定理证明
积性函数都可用线性筛法求解
一个大于1的数n可以写成
线性筛
void init()
{
for (int i = 2; i < N; i ++)
{
if (!st[i])
{
prime[cnt ++] = i;
// 1
}
for (int j = 0; prime[j] * i <= n; j ++)
{
st[prime[j] * i] = true;
if (i % prime[j] == 0)
{
// 2
break;
}
// 3
}
}
}
线性筛的原理就不解释了,我们要知道的是每个数是被自己最小的质因子筛掉的就行,这里我们看1,2,3三个地方分别是什么含义。
标号1是质数的时候。
标号2是被最小的质数筛掉,但是这个数中这个质因子出现次数>1,即存在
标号3和2最大的区别就是,标号3的位置的
那么接下来分别考虑每个函数在这三种情况时候的函数就可以轻松写出用质数筛求他们的方法。
线性筛求欧拉函数
欧拉函数的定义是: 小于或等于n的正整数中与n互质的数的数目
那么很快可以知道n为质数,也就是上述的1位置是
3位置上面说过
对于2的位置上,我们先设p是n最小质因子,
代码如下
void init()
{
phi[1] = 1;
for (int i = 2; i < N; i ++)
{
if (!st[i])
{
prime[cnt ++] = i;
phi[i] = i - 1;
// 1
}
for (int j = 0; prime[j] * i <= n; j ++)
{
st[prime[j] * i] = true;
if (i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
// 2
break;
}
phi[i * prime[j]] = phi[i] * phi[prime[j]];
// 3
}
}
}
线性筛求莫比乌斯函数
从函数就可以看出,n是质数的话就是 -1,
代码:
void init()
{
mu[1] = 1;
for (int i = 2; i < N; i ++)
{
if (!st[i])
{
prime[cnt ++] = i;
mu[i] = -1;
// 1
}
for (int j = 0; prime[j] * i <= n; j ++)
{
st[prime[j] * i] = true;
if (i % prime[j] == 0)
{
mu[i * prime[j]] = 0;
// 2
break;
}
mu[i * prime[j]] = -mu[i];
// 3
}
}
}
线性筛求约数个数
首先我们用式子表示一下n的约数个数,
我们用
标号1质数的部分
标号2的地方是
标号3的地方是
void init()
{
d[1] = 1;
for (int i = 2; i < N; i ++)
{
if (!st[i])
{
prime[cnt ++] = i;
d[i]=2, num[i] = 1;
// 1
}
for (int j = 0; prime[j] * i <= n; j ++)
{
st[prime[j] * i] = true;
if (i % prime[j] == 0)
{
// 2
num[i * prime[j]] = num[i] + 1;
d[i * prime[j]] = d[i] * (num[i * prime[j]] + 1) / (num[i] + 1);
break;
}
// 3
num[i * prime[j]] = 1;
d[i * prime[j]] = d[i] * d[prime[j]]
}
}
}
线性筛求约数和
这个和求约数个数差不多, 我们先来看约数和是如何表示的。
我们用sp数组记录最小质因子的等比数列, 用sd数组记录约数和。
标号2的部分,
代码如下:
void init()
{
sp[1] = 1;
for (int i = 2; i < N; i ++)
{
if (!st[i])
{
prime[cnt ++] = i;
d[i]=2, num[i] = 1;
sd[i] = sp[i] = i + 1;
// 1
}
for (int j = 0; prime[j] * i <= n; j ++)
{
st[prime[j] * i] = true;
if (i % prime[j] == 0)
{
// 2
sp[i * prime[j]]=sp[i] * prime[j] + 1;
sd[i * prime[j]]=sd[i] / sp[i] * sp[i * prime[j]];
break;
}
// 3
sd[i * prime[j]] = sd[i] * sd[prime[j]];
sp[i * prime[j]] = 1 + prime[j];
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现