题目
给定 个正整数 ,请你输出这些数的乘积的约数之和,答案对 取模。
输入格式
第一行包含整数 。
接下来 行,每行包含一个整数 。
输出格式
输出一个整数,表示所给正整数的乘积的约数之和,答案需对 取模。
数据范围
,
输入样例:
3
2
6
8
输出样例:
252
解题
方法一:数学
思路
由算术基本定理,对一个正整数 进行分解质因数: 。
那么 的约数之和为:
证明:
的质因数 的约数为: ,那么同理, 的约数为: 。
实际上 的约数是在 每一个点约数中分别挑一个相乘得来的,所以一共有约数个数种挑法,由乘法原理算出它们的和为: 。
本题求的是 个数乘在一起的约数之和,具体做法是:把每个数都分别做质因数分解,统计并累和每个质因子的指数,然后根据上面给出的公式算出约数之和。
分解质因数的做法见:【数学】分解质因数。
代码
import java.util.*;
import java.io.*;
public class Main {
static final int MOD = (int) 1e9 + 7;
static Map<Integer, Integer> mp;
static void pf(int n) {
for (int i = 2; i <= n / i; ++i) {
if (n % i == 0) {
int s = 0;
while (n % i == 0) {
n /= i;
++s;
}
mp.put(i, mp.getOrDefault(i, 0) + s);
}
}
if (n > 1) mp.put(n, mp.getOrDefault(n, 0) + 1);
}
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
int n = (int) in.nval;
mp = new HashMap<>();
while (n-- > 0) {
in.nextToken();
pf((int) in.nval);
}
long sum = 1L;
for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {
int p = entry.getKey(), a = entry.getValue();
long tmp = 1L;
while (a-- > 0) tmp = (tmp * p + 1) % MOD;
sum = sum * tmp % MOD;
}
System.out.println(sum);
}
}
#include <iostream>
#include <unordered_map>
using namespace std;
typedef long long LL;
const int MOD = 1e9 + 7;
unordered_map<int, int> mp;
void pf(int n) {
for (int i = 2; i <= n / i; ++i) {
if (n % i == 0) {
int s = 0;
while (n % i == 0) {
n /= i;
++s;
}
mp[i] += s;
}
}
if (n > 1) ++mp[n];
}
int main() {
int n;
scanf("%d", &n);
while (n--) {
int a;
scanf("%d", &a);
pf(a);
}
LL sum = 1L;
for (auto& pr : mp) {
int p = pr.first, a = pr.second;
LL tmp = 1L;
while (a--) tmp = (tmp * p + 1) % MOD;
sum = (sum * tmp) % MOD;
}
printf("%d\n", sum);
return 0;
}
评论区