约数个数定理

约数个数定理

定理

对于一个大于1的正整数n可以分解质因数: n = ∏ i = 1 k p i α i = p 1 α 1 ∗ p 2 α 2 ⋯ p k α k n=\prod \limits _{i=1}^{k}p_i^{\alpha_i}=p_1^{\alpha _1}*p_2^{\alpha _2}\cdots p_k^{\alpha _k} n=i=1kpiαi=p1α1p2α2pkαk。则n的正约数的个数就是f(n)= ∏ i = 1 k ( α i + 1 ) = ( α 1 + 1 ) ( α 2 + 1 ) ⋯ ( α k + 1 ) \prod \limits _{i=1}^{k}(\alpha _i+1)=(\alpha _1+1)(\alpha _2+1)\cdots(\alpha _k+1) i=1k(αi+1)=(α1+1)(α2+1)(αk+1)。其中 α 1 \alpha _1 α1 α 2 \alpha _2 α2 ⋯ \cdots α k \alpha _k αk p 1 p_1 p1 p 2 p_2 p2 ⋯ \cdots p k p_k pk的指数。


证明

对任意一个整数n,都可以分解质因数,即 n = p 1 α 1 ∗ p 2 α 2 ∗ ⋯ ∗ p k α k n=p_1^{\alpha_1}*p_2^{\alpha _2}*\cdots*p_k^{\alpha _k} n=p1α1p2α2pkαk。由约数的定义可知, p 1 α 1 p_1^{\alpha _1} p1α1的约数有: p 1 0 、 p 1 1 、 ⋯ 、 p 1 α 1 p_1^0、p_1^1、\cdots 、p_1^{\alpha _1} p10p11p1α1,总共有 ( α 1 + 1 ) (\alpha _1+1) (α1+1)个。同理可知 ⋯ \cdots p 2 α 2 p_2^{\alpha _2} p2α2的约数个数有 ( α 2 + 1 ) (\alpha _2+1) (α2+1)个, p k α k p_k^{\alpha_k} pkαk的约数个数有 ( α k + 1 ) (\alpha _k+1) (αk+1)个。从 p 1 α 1 p_1^{\alpha _1} p1α1从可以挑选出 ( α 1 + 1 ) (\alpha _1+1) (α1+1)个因子,同理, ⋯ \cdots ,从 p k α k p_k^{\alpha _k} pkαk中可以挑选出 ( α k + 1 ) (\alpha _k+1) (αk+1)个因子。由乘法原理可知,n的约数个数就是 ( α 1 + 1 ) ∗ ( α 2 + 1 ) ∗ ⋯ ∗ ( α k + 1 ) (\alpha _1+1)*(\alpha _2+1)*\cdots *(\alpha _k+1) (α1+1)(α2+1)(αk+1)

例题

正整数378000共有多少个正约数

解:将378000分解质因数378000= 2 4 × 3 3 × 5 3 × 7 1 2^4\times 3^3\times 5^3\times 7^1 24×33×53×71

由约数个数定理可知378000共有正约数(4+1)×(3+1)×(3+1)×(1+1)=160个。


题目描述

在这里插入图片描述


核心思路

这一题可以用约数个数定理来求解。


代码

#include<iostream>
#include<unordered_map>
using namespace std;
const int mod = 1e9 + 7;
typedef long long LL;
int main()
{
    int n;
    cin >> n;
    // 记录质数,使用哈希表因为如果使用数组一会遍历时会把不是质数的也遍历进去
    //第一个int是底数  第二个int是指数
    unordered_map<int, int>primes;//使用哈希表来存储质因数(底数)和这个质因数的质数
    while (n--)
    {
        int x;
        cin >> x;
        //对x这个整数进行分解质因数的操作
        for (int i = 2; i <= x / i; i++)
        {
            while (x % i == 0)
            {
                //这里表示i这个质因数(底数)它的指数的个数+1
                primes[i]++;//primes[i]是第二个int即表示指数
                x /= i;
            }
        }
        //记录大于sqrt(x)的那个质数它的指数的个数
        if (x > 1)
            primes[x]++;
    }
    LL res = 1;
    for (auto it : primes)
        res = res * (it.second + 1) % mod;//约数个数定理
    cout << res << endl;
    return 0;
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷心菜不卷Iris

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值