60.Acwing基础课第870题-简单-约数之和
60.Acwing基础课第870题-简单-约数之和
题目描述
给定\(n\)个正整数 \(a_i\),请你输出这些数的乘积的约数个数,答案对 109+7 取模。
输入格式
第一行包含整数 \(n\)。
接下来 \(n\) 行,每行包含一个整数 \(a_i\)。
输出格式
输出一个整数,表示所给正整数的乘积的约数个数,答案需对109+7 取模。
输出格式
数据范围
1≤\(n\)≤100
1≤\(a_i\)≤2×109
输入样例:
3
2
6
8
输出样例:
12
代码:
// 包含输入输出流头文件(cin/cout依赖)
#include <iostream>
// 算法库(本代码未直接使用,属于通用模板保留)
#include <algorithm>
// 哈希表:用于存储质因子及其总指数(键=质因子,值=所有数中该质因子的总指数)
#include <unordered_map>
// 向量容器(本代码未使用,属于通用模板保留)
#include <vector>
// 使用std命名空间,避免重复写std::
using namespace std;
// 定义长整型别名:防止大数运算溢出(约数之和计算可能超出int范围)
typedef long long LL;
// 常量定义:
// N=110:测试用例数量上限(题目中n≤100,留冗余)
// mod=1e9+7:题目要求结果对10^9+7取模,竞赛常用模数
const int N = 110, mod = 1e9 + 7;
int main()
{
int n; // n:输入的正整数个数(最终求这n个数乘积的约数之和)
cin >> n;
// 哈希表primes:统计所有数分解后,每个质因子的总指数
// 例如:输入2和4,2=2^1,4=2^2 → primes[2] = 1+2=3
unordered_map<int, int> primes;
// 循环处理n个输入的正整数
while (n -- )
{
int x; // x:当前要分解质因数的数
cin >> x;
// 质因数分解核心:枚举2到√x的所有数(i<=x/i等价于i<=sqrt(x),避免浮点误差)
for (int i = 2; i <= x / i; i ++ )
// 若i是x的质因子,循环除净x中所有的i,并统计指数
while (x % i == 0)
{
x /= i; // 把x中的i除干净(确保后续i是质因子)
primes[i] ++ ; // 该质因子的总指数+1
}
// 若循环结束后x>1,说明x本身是一个大于√原数的质因子,统计其指数
if (x > 1) primes[x] ++ ;
}
LL res = 1; // 存储最终约数之和,初始为1(乘法单位元,不影响乘积)
// 遍历所有质因子,应用「约数之和定理」计算总结果
for (auto p : primes)
{
LL a = p.first; // a:当前质因子(如2、3、5...)
LL b = p.second; // b:该质因子的总指数(如2^6的6)
LL t = 1; // t:存储当前质因子的幂和(a^0 + a^1 + ... + a^b),初始为a^0=1
// 递推计算幂和:避免直接算高次幂,防止溢出且效率高
while (b -- )
{
// 递推公式解析:
// 初始t=1(a^0)
// 第1次循环:t = 1*a + 1 = a+1(a^0+a^1)
// 第2次循环:t = (a+1)*a + 1 = a²+a+1(a^0+a^1+a²)
// 第b次循环:得到a^0+a^1+...+a^b
t = (t * a + 1) % mod; // 每次计算后取模,防止溢出
}
// 约数之和定理:总约数和 = 各质因子幂和的乘积(取模)
res = res * t % mod;
}
// 输出最终的约数之和
cout << res << endl;
return 0; // 程序正常结束
}

浙公网安备 33010602011771号