Advertisement
Guest User

my code with eratosth-sieve

a guest
Jan 4th, 2017
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.75 KB | None | 0 0
  1. -------------------------  SIEVE OF ERATOSTHENES
  2.  
  3. local function get_array_of_primes(max_number)  -- max_number >= 0
  4.    -- returns array {2, 3, 5,...} of all primes <= max_number
  5.    local primes = {2, 3, 5, 7}
  6.    local primes_cnt = 4
  7.    -- sieve contains only odd numbers starting from 15
  8.    local sieve = {}  -- sieve[idx]==true iff (2*idx+13) is composite
  9.    local max_idx = (max_number - 13) / 2
  10.    -- Marking only multiples of 3, 5 would impact performance due to sparseness of the table:
  11.    -- to minimize using hash part of Lua table we must fill more than half elements
  12.    -- That's why we are marking multiples of 3, 5, 7  (density = 1-(2/3)*(4/5)*(6/7) = 0.543 > 50%)
  13.    for idx = 1, max_idx, 3*5*7 do
  14.       sieve[idx] = true
  15.       sieve[idx + 3] = true
  16.       sieve[idx + 5] = true
  17.       sieve[idx + 6] = true
  18.       sieve[idx + 9] = true
  19.       sieve[idx + 10] = true
  20.       sieve[idx + 12] = true
  21.       sieve[idx + (15 + 0)] = true
  22.       sieve[idx + (3 + 7*2)] = true
  23.       sieve[idx + (15 + 3)] = true
  24.       sieve[idx + (15 + 5)] = true
  25.       sieve[idx + (15 + 6)] = true
  26.       sieve[idx + (15 + 9)] = true
  27.       sieve[idx + (15 + 10)] = true
  28.       sieve[idx + (15 + 12)] = true
  29.       sieve[idx + (15*2 + 0)] = true
  30.       sieve[idx + (3 + 7*4)] = true
  31.       sieve[idx + (15*2 + 3)] = true
  32.       sieve[idx + (15*2 + 5)] = true
  33.       sieve[idx + (15*2 + 6)] = true
  34.       sieve[idx + (3 + 7*5)] = true
  35.       sieve[idx + (15*2 + 9)] = true
  36.       sieve[idx + (15*2 + 10)] = true
  37.       sieve[idx + (15*2 + 12)] = true
  38.       sieve[idx + (15*3 + 0)] = true
  39.       sieve[idx + (15*3 + 3)] = true
  40.       sieve[idx + (15*3 + 5)] = true
  41.       sieve[idx + (15*3 + 6)] = true
  42.       sieve[idx + (3 + 7*7)] = true
  43.       sieve[idx + (15*3 + 9)] = true
  44.       sieve[idx + (15*3 + 10)] = true
  45.       sieve[idx + (15*3 + 12)] = true
  46.       sieve[idx + (3 + 7*8)] = true
  47.       sieve[idx + (15*4 + 0)] = true
  48.       sieve[idx + (15*4 + 3)] = true
  49.       sieve[idx + (15*4 + 5)] = true
  50.       sieve[idx + (15*4 + 6)] = true
  51.       sieve[idx + (15*4 + 9)] = true
  52.       sieve[idx + (15*4 + 10)] = true
  53.       sieve[idx + (15*4 + 12)] = true
  54.       sieve[idx + (3 + 7*10)] = true
  55.       sieve[idx + (15*5 + 0)] = true
  56.       sieve[idx + (15*5 + 3)] = true
  57.       sieve[idx + (15*5 + 5)] = true
  58.       sieve[idx + (15*5 + 6)] = true
  59.       sieve[idx + (15*5 + 9)] = true
  60.       sieve[idx + (15*5 + 10)] = true
  61.       sieve[idx + (15*5 + 12)] = true
  62.       sieve[idx + (15*6 + 0)] = true
  63.       sieve[idx + (15*6 + 3)] = true
  64.       sieve[idx + (3 + 7*13)] = true
  65.       sieve[idx + (15*6 + 5)] = true
  66.       sieve[idx + (15*6 + 6)] = true
  67.       sieve[idx + (15*6 + 9)] = true
  68.       sieve[idx + (15*6 + 10)] = true
  69.       sieve[idx + (3 + 7*14)] = true
  70.       sieve[idx + (15*6 + 12)] = true
  71.    end
  72.    local root_max_number = math.sqrt(max_number) + 0.01
  73.    local factor_idx = -1
  74.    local factor = 11
  75.    repeat
  76.       primes_cnt = primes_cnt + 1
  77.       primes[primes_cnt] = factor
  78.       for idx = (factor * factor - 13) / 2, max_idx, factor do
  79.          sieve[idx] = true
  80.       end
  81.       repeat
  82.          factor_idx = factor_idx + 1
  83.       until not sieve[factor_idx]
  84.       factor = 2 * factor_idx + 13
  85.    until factor > root_max_number
  86.    primes_cnt = primes_cnt + 1
  87.    primes[primes_cnt] = factor
  88.    repeat
  89.       repeat
  90.          factor_idx = factor_idx + 1
  91.       until not sieve[factor_idx]
  92.       primes_cnt = primes_cnt + 1
  93.       primes[primes_cnt] = 2 * factor_idx + 13
  94.    until factor_idx >= max_idx
  95.    return primes
  96. end
  97.  
  98. -- get array of first 100000 primes  (it takes 0.13 seconds)
  99. local primes = get_array_of_primes(1299709)
  100. ---------------------------------------------
  101.  
  102.  
  103.  
  104. --  precalculate all G[m] (it takes 0.12 sec)
  105. local G = {}
  106. local g = 1
  107. for k = 1, 100000 do
  108.    local b, s, p, n = 1000000007, primes[k]-1, 0, 1
  109.    while s > 1 do
  110.       local r = b % s
  111.       p, n = n, p + (r - b) / s * n
  112.       b, s = s, r
  113.    end
  114.    local ii = n % 1000000007
  115.    local L = ii % 65536
  116.    local H = (ii - L) / 65536
  117.    g = (H * g % 1000000007 * 65536 + g * L) % 1000000007
  118.    g = (H * g % 1000000007 * 65536 + g * L) % 1000000007
  119.    G[k] = g
  120. end
  121.  
  122.  
  123.  
  124. --~ io.input("input.txt")
  125.  
  126. -------------------------------------------------------------------------------------
  127. --  MAIN LOOP
  128. -------------------------------------------------------------------------------------
  129.  
  130. for _ = 1, io.read"*n" do
  131.    local m, a = io.read("*n", "*n")
  132.    local result = G[m]       -- this value has already been precalculated
  133.    local a2 = a + 2
  134.    for k = 1, m do
  135.       ------------------------------------------------------------------------
  136.       -- The body of this inner loop is executed up to 3.9 million times
  137.       ------------------------------------------------------------------------
  138.       local p = primes[k]    -- this value has already been precalculated
  139.       local ak2 = a2 + k     -- 3 <= ak2 < 2^18
  140.       -- Next 16 lines calculate:  W = p^ak2
  141.       local exponent = ak2
  142.       local mask = 131072    -- 2^17
  143.       while mask > exponent do
  144.          mask = mask / 2
  145.       end
  146.       exponent = exponent - mask
  147.       local W = p
  148.       while mask > 1 do
  149.          local R = W % 65536
  150.          W = ((W - R) / 65536 * W % 1000000007 * 65536 + W * R) % 1000000007
  151.          mask = mask / 2
  152.          if exponent >= mask then
  153.             exponent = exponent - mask
  154.             W = W * p % 1000000007
  155.          end
  156.       end
  157.       -- Next 3 lines calculate:  result = result * (W - 1 - (p - 1) * ak2)
  158.       local W = (W - 1 - (p - 1) * ak2) % 1000000007
  159.       local R = W % 65536
  160.       result = ((W - R) / 65536 * result % 1000000007 * 65536 + result * R) % 1000000007
  161.       ------------------------------------------------------------------------
  162.    end
  163.    print(result)
  164. end
  165.  
  166. --~ print(os.clock())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement