870. Números divididos y 871. Sumas divididas

Dados n enteros positivos ai, genere el número de divisores del producto de estos números y la respuesta es módulo 1e9 + 7.

formato de entrada

La primera línea contiene el número entero n.

Las siguientes n líneas, cada línea contiene un número entero ai.

formato de salida

Genere un número entero que represente el número de divisores del producto de los números enteros positivos dados. La respuesta debe ser módulo 1e9+7.

rango de datos

1≤n≤100,
1≤ai≤2×109

Muestra de entrada:

3
2
6
8

Salida de muestra:

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;
			}
		}
	}
}

aproximación y

Dados n enteros positivos ai, genere la suma de los divisores de los productos de estos números y la respuesta es módulo 109 + 7.

formato de entrada

La primera línea contiene el número entero n.

Las siguientes n líneas, cada línea contiene un número entero ai.

formato de salida

Genere un número entero que represente la suma de los divisores del producto de los números enteros positivos dados. La respuesta debe ser módulo 109+7.

rango de datos

1≤n≤100,
1≤ai≤2×109

Muestra de entrada:

3
2
6
8

Salida de muestra:

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;
}

Supongo que te gusta

Origin blog.csdn.net/zhi6fui/article/details/128641768
Recomendado
Clasificación