vector<int> segmentedSieve(int n) {
int limit = floor(sqrt(n)) + 1;
vector<int> primes; sieve_of_eratosthenes(limit, primes);
vector<int> all_primes(primes);
int low = limit, high = 2 * limit;
while (low < n) {
if (high >= n) high = n;
bool mark[limit + 1]; memset(mark, true, sizeof(mark));
for (int i = 0; i < primes.size(); ++i) {
int loLim = (low / primes[i]) * primes[i];
if (loLim < low) loLim += primes[i];
for (int j = loLim; j < high; j += primes[i]) mark[j - low] = false;
}
for (int i = low; i < high; ++i) if (mark[i - low]) all_primes.push_back(i);
low += limit;
high += limit;
}
return all_primes;
}// Time: O(n * ln(sqrt(n))), Space: O(sqrt(n))
vector<int> sumaDivisores(int n){
vector<int> criba(n + 1, 1);
criba[0] = 0;
for (int i = 2; i <= n; ++i) {
for (int j = i * 2; j <= n; j += i) {
criba[j] += i;
}
}
return criba;
}
vector<int> factors(int n) {
vector<int> f;
for (int i = 2; i*i <= n; ++i) {
while (n%i == 0) {
f.push_back(x);
n /= i;
}
}
if (n > 1) f.push_back(n);
return f;
}
El algoritmo de Euclides es la forma más eficiente de calcular el GCD utilizando divisiones sucesivas:
int gcd(int a,int b) {
return b == 0 ? a : gcd(b, a % b);
}//O(log(min(a,b)))
int lcm(int a,int b) {
return (a / gcd(a, b)) * b; // evitando overflow
}//O(log(min(a,b)))
Si estás utilizando una versión de C++ menor a C++17, puedes usar la función
__gcd
teniendo cuidado con el caso__gcd(0,0)
y manualmente declarar la funcion delcm
si la llegas a necesitar.
La función totiente de Euler
int phi(int n) {
int result = n;
for(int p = 2; p * p <= n; ++p) {
if (n % p == 0) {
while (n % p == 0) n /= p;
result -= result / p;
}
}
if (n > 1) result -= result / n;
return result;
} // O(Φ n log n)
El Teorema Pequeño de Fermat (no confundir con el Último Teorema de Fermat) establece que todos los enteros
En consecuencia,
Por lo tanto,
long long mod_exp(long long base, long long exp, long long MOD) {
long long result = 1;
while (exp > 0) {
if (exp % 2 == 1) {
result = (result * base) % MOD;
}
base = (base * base) % MOD;
exp /= 2;
}
return result;
}
// Función para calcular (a / b) % MOD
long long divide_mod(long long a, long long b, long long MOD) {
long long b_inv = mod_exp(b, MOD - 2, MOD); // b^(MOD-2) % MOD
return (a * b_inv) % MOD;
}