约数函数

本文详细解析了如何利用线性筛算法高效求解σ和d两个积性函数,通过对σ函数的深入探讨,提供了具体的算法实现思路,并简要介绍了d函数的计算方法。

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

众所周知,\(d\)\(\sigma\)都是积性函数,今天我们来对这俩动刀子。

我打算只讲稍难\(\sigma\),剩下的那个\(d\),留给大家自己思考。

根据定义得到:

\(\begin{aligned}\sigma(p^k)=1+p+p^2+...+p^k\end{aligned}\)

然后我们就能推导出\(\sigma\)的求值式:

\(\begin{aligned}n=\prod_{i=1}p_i^{c_i}\end{aligned},\)

\(\begin{aligned}\sigma(n)=\prod_{i=1}1+p_i+p_i^2...+p_i^{c_i}\end{aligned}\)

尝试用线性筛构造这个函数:

\(x=i\times p_1\),其中\(p\)\(x\)的最小质因子,\(\begin{aligned}x=\prod_{i=1}p_i^{c_i}\end{aligned}\)

  • \(x\)为质数:\(\sigma(x)=1+x\)

  • \(i\)\(p_1\)互质时:\(\sigma(x)=\sigma(i)\times\sigma(p_1)\)

  • \(i\%p_1=0\)时:

    我们具体来讨论一下这个情况。

    \(\begin{aligned}\sigma(x)=\prod_{i=1}1+p_i+p_i^2+...+p_i^{c_i}\end{aligned}\)

    \(\begin{aligned}\sigma(i)=(1+p_1+p_2^2+..+p_1^{c_1-1})\prod_{i=2}1+p_i+p_i^2+...+p_i^{c_i-1}\end{aligned}\)

    我们想要直接通过\(\sigma(i)\)来求\(\sigma(x)\)显然是不现实的,因为我们不知道\(c_1\)是多少。

    那么我们应该怎么做呢?

    我们尝试把这个包含绝对关系的式子转换成包含相对关系的式子。

    因为我们\(x\)\(i\),从第二项开始就是一样的了,所以我们可以设:\(\begin{aligned}T=\prod_{i=2}1+p_i+p_i^2+p_i^{c_i}\end{aligned}\)

    然后式子就转换为了:

    \(\begin{aligned}\sigma(x)=\sigma(i)+p_1^{c_1}\times T\end{aligned}\)

    我们来考虑一下怎么把这个讨厌的\(p_1^{c_1}\)给处理了。

    注意我们一开始的目标:把绝对关系转化成相对关系。

    既然我们不知道\(p_1^{c_1}\times T\)的值,那么我们能不能求出\(p_1^{c_1-1}\times T\)的值呢?

    注意到\(\begin{aligned}\sigma(i)=\sigma(\frac i {p_1})+p_1^{c_1-1}\times T\end{aligned}\)

    然后怎么做应该就不用我多说了吧——盘他!

    \(\begin{aligned}\sigma(x)&=\sigma(i)+p\times(\sigma(i)-\sigma(\frac i {p_1}))\\&=(1+p)\times\sigma(i)-p\times\sigma(\frac i{p_1})\end{aligned}\)

然后我们就能直接用线性筛来求约数函数了。


最后,我在稍微写一下\(d\)的式子吧:

\(\begin{aligned}d(x)=2\times d(i)-d(\frac i {p_1})\end{aligned}\)

转载于:https://www.cnblogs.com/WR-Eternity/p/11023518.html

### 实现最大公约数函数的方法 最大公约数(Greatest Common Divisor, GCD)是指两个或多个整数共有约数中最大的一个。计算最大公约数的经典算法是欧几里得算法,其核心思想基于以下性质:对于任意两个正整数 \(a\) 和 \(b\),如果 \(a \geq b\),则有: \[ \text{gcd}(a, b) = \text{gcd}(b, a \% b) \] 当 \(b = 0\) 时,\(a\) 即为两者的最大公约数。 以下是使用 C++ 编写的一个简单的递归版本的最大公约数函数实现[^4]: ```cpp int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } ``` 此外,也可以通过迭代方式实现该功能,如下所示[^5]: ```cpp int gcd(int a, int b) { while (b != 0) { int temp = a % b; a = b; b = temp; } return a; } ``` 上述两种方法均利用了欧几里得算法的核心原理,并且时间复杂度均为 \(O(\log(\min(a,b)))\)。 在实际应用中,C++ 标准库 `<algorithm>` 提供了一个内置的 `std::gcd` 函数用于求解最大公约数,简化了开发工作量。例如: ```cpp #include <iostream> #include <algorithm> int main() { int a = 56, b = 98; std::cout << "GCD of " << a << " and " << b << " is: " << std::gcd(a, b) << std::endl; return 0; } ``` 以上代码展示了如何调用标准库中的 `std::gcd` 来快速获取两个整数的最大公约数[^6]。 ### 注意事项 尽管标准库提供了便捷的功能,但在某些特定场景下可能仍需手动实现自定义逻辑,比如处理负数或者浮点数的情况。此时应特别注意边界条件以及数据类型的兼容性问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值