给定 n 个正整数 ai,请你输出这些数的乘积的约数个数,答案对 1e9+7 取模。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个整数 ai。
输出格式
输出一个整数,表示所给正整数的乘积的约数个数,答案需对 1e9+7取模。
数据范围
1≤n≤100,
1≤ai≤2×109
输入样例:
3
2
6
8
输出样例:
12
//筛法求约数个数
int cnt;
int a[N];//记录最小质因子的个数
int d[N];//记录i的约数个数
void get(int n) {
int visits[N];
cnt = 0;
d[1] = 1;
memset(visits, 0, sizeof(visits));
memset(prime, 0, sizeof(prime));
memset(a, 0, sizeof(a));
memset(d, 0, sizeof(d));
//线性筛法
for (int i = 2; i <= n; i++) {
if (!visits[i]) {
prime[++cnt] = i;
a[i] = 1;
d[i] = 2;
}
for (int j = 1; j <= cnt; j++) {
int m = prime[j] * i;
if (m > n) break;
visits[m] = 1;
if (i % prime[j] == 0) { // prime[j]*i的最小质因子都是 prime[j]
a[m] = a[i] + 1;//a记录最小质因子 它比a[i]多了一个prime[j]
d[m] = d[i] / a[m] * (a[m] + 1);
break;
}
else {
a[m] = 1;// i
d[m] = d[i] * 2;
}
}
}
}
约数和
给定 n 个正整数 ai,请你输出这些数的乘积的约数之和,答案对 109+7 取模。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个整数 ai。
输出格式
输出一个整数,表示所给正整数的乘积的约数之和,答案需对 109+7 取模。
数据范围
1≤n≤100,
1≤ai≤2×109
输入样例:
3
2
6
8
输出样例:
252
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3;
int prime[N + 1];
bool visit[N + 1];
int vis[N + 1];
//线性筛法
int prime_visit(int n) {
int cnt = 0;
memset(vis, 0, sizeof(vis));
memset(prime, 0, sizeof(prime));
for (int i = 2; i <= n; i++) {
if (!vis[i]) vis[i] = i, prime[cnt++] = i;
for (int j = 0; j < cnt; j++) {
if (prime[j] * i > n) break;
visit[prime[j] * i] = prime[j];// 记录最小的质因数
if (i % prime[j] == 0) break;
}
}
return cnt;
}
// 试除法分解质因数 (只能对一个数做因式分解)
int c[40]; // 记录第i个因数的个数
int p[40];//p[1]是最小因数 p[ ]记录因数
int factor(int n) {
int m = 0;
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
p[++m] = i, c[m] = 0;
while (n % i == 0) n /= i, c[m]++;
}
}
if (n > 1) p[++m] = n, c[m] = 1;
return m;
}
//筛法求约数个数
int cnt;
int a[N];//记录最小质因子的个数
int d[N];//记录i的约数个数
void get(int n) {
int visits[N];
cnt = 0;
d[1] = 1;
memset(visits, 0, sizeof(visits));
memset(prime, 0, sizeof(prime));
memset(a, 0, sizeof(a));
memset(d, 0, sizeof(d));
//线性筛法
for (int i = 2; i <= n; i++) {
if (!visits[i]) {
prime[++cnt] = i;
a[i] = 1;
d[i] = 2;
}
for (int j = 1; j <= cnt; j++) {
int m = prime[j] * i;
if (m > n) break;
visits[m] = 1;
if (i % prime[j] == 0) { // prime[j]*i的最小质因子都是 prime[j]
a[m] = a[i] + 1;//a记录最小质因子 它比a[i]多了一个prime[j]
d[m] = d[i] / a[m] * (a[m] + 1);
break;
}
else {
a[m] = 1;// i
d[m] = d[i] * 2;
}
}
}
}
int g[N]; //1 + p^1 + ```+p^k
int f[N];// 第i个的约数和
void get_f(int n) {
g[1] = 1;
f[1] = 1;
memset(visit, false, sizeof(visit));
memset(prime, 0, sizeof(prime));
int cnt = 0;
for (int i = 2; i <= n; i++) {
if (!visit[i])
{
prime[++cnt] = i;
g[i] = 1 + i;
f[i] = i + 1;
}
for (int j = 1; j <= cnt; j++) {
int m = i * prime[j];
if (m > n) { break; }
visit[m] = true;
if (i % prime[j] == 0) { // prime[j]是最小共因数
g[m] = g[i]*prime[j] +1;
f[m] = f[i] / g[i] * g[m];
break;
}
else {
g[m] = prime[j] + 1;
f[m] = f[i] * g[m];
}
}
}
}
int main() {
get(30);
cout << d[10] << endl;
get_f(30);
cout << f[12];
return 0;
}