--sas

Untitled

May 22nd, 2019
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.46 KB | None | 0 0
  1. #include <vector>
  2. #include <utility>
  3. #include <cmath>
  4.  
  5. using namespace std;
  6.  
  7. vector<uint64_t> erat(uint64_t N) {
  8.     typedef std::pair<std::vector<char>::iterator, unsigned int> bit;
  9.  
  10.     auto do_step = [] (bit& b, uint64_t s) -> void {
  11.         uint64_t dist = b.second + s;
  12.         b.first += dist / 8u;
  13.         b.second = dist % 8u;
  14.     };
  15.  
  16.     auto is_prime = [] (const bit& b) -> bool {
  17.         return static_cast<bool>(*(b.first) & (1 << b.second));
  18.     };
  19.  
  20.     auto next_prime = [&do_step, &is_prime] (uint64_t& prime, bit& b) -> void {
  21.         do {
  22.             do_step(b, 1u);
  23.             prime += 2u;
  24.         } while (!is_prime(b));
  25.     };
  26.  
  27.     auto make_false = [] (bit& b) -> void {
  28.         *(b.first) &= ~(1 << b.second);
  29.     };
  30.  
  31.     auto index = [] (uint64_t num) -> uint64_t {
  32.         return (num - 3u) / 2u;
  33.     };
  34.  
  35.     vector<char> bits(N / 16 + 1, -1);
  36.     vector<uint64_t> primes({2});
  37.  
  38.     uint64_t p = 3;
  39.     bit b(bits.begin(), 0u);
  40.     auto max = static_cast<uint64_t>(sqrt(N)) + 1u;
  41.  
  42.     while(p < max) {
  43.         bit comp(bits.begin(), 0u);
  44.         do_step(comp, index(p * p));
  45.         for (comp; comp.first < bits.end(); do_step(comp, p))
  46.             make_false(comp);
  47.  
  48.         primes.push_back(p);
  49.         next_prime(p, b);
  50.     }
  51.  
  52.     while (b.first < bits.end()) {
  53.         primes.push_back(p);
  54.         next_prime(p, b);
  55.     }
  56.  
  57.     while (*primes.rbegin() > N)
  58.         primes.pop_back();
  59.  
  60.     return primes;
  61. }
Advertisement
Add Comment
Please, Sign In to add comment