题目
给定 个正整数 ,请你输出这些数的乘积的约数个数,答案对 取模。
输入格式
第一行包含整数 。
接下来 行,每行包含一个整数 。
输出格式
输出一个整数,表示所给正整数的乘积的约数个数,答案需对 取模。
数据范围
,
输入样例:
3
2
6
8
输出样例:
12
解题
方法一:数学
思路
由算术基本定理,对一个正整数 进行分解质因数: 。
那么 的约数个数为:
证明:
的任何一个约数 可以质因数分解表示为: 。
每一项的 如果不同,那约数 就一定不同(由算术基本定理可知每个数的质因数分解是唯一的)。
所以 的约数与其约数每一项选择 的选法是对应的,故 的约数个数与选法的个数时相同的。对于 的约数来说: 一共有 共 种选法、 一共有 共 种选法 …… 一共有 共 种选法。根据乘法原理,一共就有 种选法。
本题求的是 个数乘在一起的约数个数,具体做法是:把每个数都分别做质因数分解,统计并累和每个质因子的指数,然后根据上面给出的公式就能算出约数个数。
分解质因数的做法见:【数学】分解质因数。
代码
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 cnt = 1;
for (int v : mp.values()) {
cnt = cnt * (v + 1) % MOD;
}
System.out.println(cnt);
}
}
#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 cnt = 1L;
for (auto& pr : mp) cnt = (cnt * (pr.second + 1)) % MOD;
printf("%d\n", cnt);
return 0;
}
评论区