Простые числа. Решето Эратосфена: различия между версиями

Материал из Олимпиадное программирование в УлГТУ
Перейти к навигации Перейти к поиску
Нет описания правки
 
(не показаны 3 промежуточные версии этого же участника)
Строка 1: Строка 1:
===Проверка числа на простоту, O(sqrt(N))===
===Проверка числа на простоту, O(sqrt(N))===
{| width="100%"
| width=50% |
  bool isPrime(int n) {
  bool isPrime(int n) {
     if (n < 2)
     if (n < 2)
Строка 10: Строка 12:
     return 1;
     return 1;
  }
  }
| width="10px" | &nbsp;
| width=50% |
bool isPrime(int n) {
    if (n < 2)
        return 0;
    static vector<int> primes = getPrimes(1e5);
    for (int i = 0; 1LL * primes[i] * primes[i] <= n; i++)
        if (n % primes[i] == 0)
            return 0;
    return 1;
}
|}


===Получение списка всех делителей числа, O(sqrt(N))===
===Получение списка делителей числа, O(sqrt(N))===
{| width="100%"
| width=50% |
  vector<int> getDivisors(int n) {
  vector<int> getDivisors(int n) {
     vector<int> divisors;
     vector<int> divisors;
Строка 26: Строка 45:
     return divisors;
     return divisors;
  }
  }
| width="10px" | &nbsp;
| width=50% |
vector<int> getPrimeDivisors(int n) {
    vector<int> primeDivisors;
   
    for (long long d = 2; d * d <= n; d++) {
        if (n % d == 0) {
            primeDivisors.push_back(d);
            while (n % d == 0)
                n /= d;
        }
    }
    if (n != 1)
        primeDivisors.push_back(n);
    return primeDivisors;
}
|}


===Факторизация числа (получение списка простых делителей), O(sqrt(N))===
===Факторизация числа (получение списка простых делителей), O(sqrt(N))===
Строка 64: Строка 102:
===Решето Эратосфена, O(NloglogN)===
===Решето Эратосфена, O(NloglogN)===


  vector<int> getPrimes() {
  vector<int> getPrimes(int n) {
    const int N = 1e6;
     vector<int> isPrime(n + 1, 1), primes;
     vector<int> isPrime(N, 1), primes;
   
     for (int i = 2; i < isPrime.size(); i++) {
     for (int i = 2; i < N; i++) {
         if (isPrime[i]) {
         if (isPrime[i]) {
             primes.push_back(i);
             primes.push_back(i);
             for (long long j = 1LL * i * i; j < N; j += i)
             for (long long j = 1LL * i * i; j < isPrime.size(); j += i)
                 isPrime[j] = 0;
                 isPrime[j] = 0;
         }
         }
     }
     }
   
     return primes;
     return primes;
  }
  }


===Решето Эратосфена, O(N)===
===Решето Эратосфена, O(N)===
  vector<int> getPrimes() {
  vector<int> getPrimes(int n) {
    const int N = 1e6;
     vector<int> minDivisor(n + 1), primes;
     vector<int> minDivisor(N), primes;
   
     for (int i = 2; i < minDivisor.size(); i++) {
     for (int i = 2; i < N; i++) {
         if (!minDivisor[i]) {
         if (!minDivisor[i]) {
             minDivisor[i] = i;
             minDivisor[i] = i;
             primes.push_back(i);
             primes.push_back(i);
         }
         }
         for (int j = 0; j < primes.size() && primes[j] <= minDivisor[i] && 1LL * i * primes[j] < N; j++)
         for (int j = 0; j < primes.size() && primes[j] <= minDivisor[i] && 1LL * i * primes[j] < minDivisor.size(); j++)
             minDivisor[i * primes[j]] = primes[j];
             minDivisor[i * primes[j]] = primes[j];
     }
     }
   
     return primes;
     return primes;
  }
  }

Текущая версия от 22:37, 14 августа 2024

Проверка числа на простоту, O(sqrt(N))

bool isPrime(int n) {
    if (n < 2)
        return 0;
    
    for (long long d = 2; d * d <= n; d++)
        if (n % d == 0)
            return 0;
    
    return 1;
}

 
bool isPrime(int n) {
    if (n < 2)
        return 0;

    static vector<int> primes = getPrimes(1e5);
    for (int i = 0; 1LL * primes[i] * primes[i] <= n; i++)
        if (n % primes[i] == 0)
            return 0;

    return 1;
}

Получение списка делителей числа, O(sqrt(N))

vector<int> getDivisors(int n) {
    vector<int> divisors;
    
    for (long long d = 1; d * d <= n; d++) {
        if (n % d == 0) {
            divisors.push_back(d);
            if (d * d != n)
                divisors.push_back(n / d);
        }
    }
    
    sort(divisors.begin(), divisors.end());
    return divisors;
}

 
vector<int> getPrimeDivisors(int n) {
    vector<int> primeDivisors;
    
    for (long long d = 2; d * d <= n; d++) {
        if (n % d == 0) {
            primeDivisors.push_back(d);
            while (n % d == 0)
                n /= d;
        }
    }
    if (n != 1)
        primeDivisors.push_back(n);

    return primeDivisors;
}

Факторизация числа (получение списка простых делителей), O(sqrt(N))

vector<int> factorize(int n) {
    vector<int> factorization;
    
    for (long long d = 2; d * d <= n; d++) {
        while (n % d == 0) {
            factorization.push_back(d);
            n /= d;
        }
    }
    if (n != 1)
       factorization.push_back(n);
    
    return factorization;
}
 
map<int, int> factorize(int n) {
    map<int, int> factorization;

    for (long long d = 2; d * d <= n; d++) {
        while (n % d == 0) {
            factorization[d]++;
            n /= d;
        }
    }
    if (n != 1)
       factorization[n]++;

    return factorization;
}

Решето Эратосфена, O(NloglogN)

vector<int> getPrimes(int n) {
    vector<int> isPrime(n + 1, 1), primes;

    for (int i = 2; i < isPrime.size(); i++) {
        if (isPrime[i]) {
            primes.push_back(i);
            for (long long j = 1LL * i * i; j < isPrime.size(); j += i)
                isPrime[j] = 0;
        }
    }

    return primes;
}

Решето Эратосфена, O(N)

vector<int> getPrimes(int n) {
    vector<int> minDivisor(n + 1), primes;

    for (int i = 2; i < minDivisor.size(); i++) {
        if (!minDivisor[i]) {
            minDivisor[i] = i;
            primes.push_back(i);
        }
        for (int j = 0; j < primes.size() && primes[j] <= minDivisor[i] && 1LL * i * primes[j] < minDivisor.size(); j++)
            minDivisor[i * primes[j]] = primes[j];
    }

    return primes;
}

Ссылки

Теория:

Код:

Задачи: