约数和定理
定理
对于一个大于1的正整数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,由约数个数定理可知,n的正约数的个数有 ( α 1 + 1 ) ( α 2 + 1 ) ⋯ ( α k + 1 ) (\alpha_1 +1)(\alpha _2+1)\cdots (\alpha_k+1) (α1+1)(α2+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)个正约数的和为: f ( n ) = ( p 1 0 + p 1 1 + ⋯ + p 1 α 1 ) ( p 2 0 + p 2 1 + ⋯ + p 2 α 2 ) ⋯ ( p k 0 + p k 1 + ⋯ + p k α k ) f(n)=(p_1^0+p_1^1+\cdots+p_1^{\alpha_1})(p_2^0+p_2^1+\cdots +p_2^{\alpha_2})\cdots (p_k^0+p_k^1+\cdots +p_k^{\alpha _k}) f(n)=(p10+p11+⋯+p1α1)(p20+p21+⋯+p2α2)⋯(pk0+pk1+⋯+pkαk)。
证明
若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, ⋯ \cdots ⋯,同理可知, p k α k p_k^{\alpha _k} pkαk的约数有: p k 0 、 p k 1 、 ⋯ p k α k p_k^0、p_k^1、\cdots p_k^{\alpha_k} pk0、pk1、⋯pkαk。实际上n的约数就是在 p 1 α 1 p_1^{\alpha _1} p1α1, p 2 α 2 p_2^{\alpha _2} p2α2, ⋯ \cdots ⋯, p k α k p_k^{\alpha _k} pkαk每一个的约数中 分别随便挑出一个因子来相乘而得到的。由乘法原理可知它们的和为: f ( n ) = ( p 1 0 + p 1 1 + p 1 2 + ⋯ + p 1 α 1 ) ( p 2 0 + p 2 1 + ⋯ + p 2 α 2 ) ⋯ ( p k 0 + p k 1 + ⋯ + p k α k ) f(n)=(p_1^0+p_1^1+p_1^2+\cdots +p_1^{\alpha _1})(p_2^0+p_2^1+\cdots +p_2^{\alpha_2})\cdots (p_k^0+p_k^1+\cdots +p_k^{\alpha _k}) f(n)=(p10+p11+p12+⋯+p1α1)(p20+p21+⋯+p2α2)⋯(pk0+pk1+⋯+pkαk)。
例题
正整数360的所有正约数的和是多少?
解:将360分解质因数可得
360= 2 3 ∗ 3 2 ∗ 5 1 2^3*3^2*5^1 23∗32∗51;
由约数和定理可知,360所有正约数的和为
( 2 0 + 2 1 + 2 2 + 2 3 ) ( 3 0 + 3 1 + 3 2 ) ( 5 0 + 5 1 ) = ( 1 + 2 + 4 + 8 ) ( 1 + 3 + 9 ) ( 1 + 5 ) = 1170 (2^0+2^1+2^2+2^3)(3^0+3^1+3^2)(5^0+5^1)=(1+2+4+8)(1+3+9)(1+5)=1170 (20+21+22+23)(30+31+32)(50+51)=(1+2+4+8)(1+3+9)(1+5)=1170。
可知360的约数有1、2、3、4、5、6、8、9、10、12、15、18、20、24、30、36、40、45、60、72、90、120、180、360;则约数之和为
1+2+3+4+5+6+8+9+10+12+15+18+20+24+30+36+40+45+60+72+90+120+180+360=1170。
题目描述
核心思路
这一题可以用约数和定理来求解。
代码
#include<iostream>
#include<unordered_map>
using namespace std;
const int mod = 1e9 + 7;
typedef long long LL;
int main()
{
int n;
cin >> n;
unordered_map<int, int>primes;
while (n--)
{
int x;
cin >> x;
//将每一个整数x都分解质因数
for (int i = 2; i <= x / i; i++)
{
while (x % i == 0)
{
primes[i]++;
x /= i;
}
}
if (x > 1)
primes[x]++;
}
LL res = 1;
//运用 约数和定理 来求解答案
for (auto it : primes)
{
LL p = it.first, a = it.second;//p是底数 a是指数
LL t = 1;
while (a--)
t = (t * p + 1) % mod;//这里也取模是防止溢出,确保中间结果不会溢出。
res = res * t % mod;
}
cout << res << endl;
return 0;
}