约数个数定理
定理
对于一个大于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=1∏kpiαi=p1α1∗p2α2⋯pkα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=1∏k(α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α1∗p2α2∗⋯∗pkα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} p10、p11、⋯、p1α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;
}