Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ------------------------- SIEVE OF ERATOSTHENES
- local function get_array_of_primes(max_number) -- max_number >= 0
- -- returns array {2, 3, 5,...} of all primes <= max_number
- local primes = {2, 3, 5, 7}
- local primes_cnt = 4
- -- sieve contains only odd numbers starting from 15
- local sieve = {} -- sieve[idx]==true iff (2*idx+13) is composite
- local max_idx = (max_number - 13) / 2
- -- Marking only multiples of 3, 5 would impact performance due to sparseness of the table:
- -- to minimize using hash part of Lua table we must fill more than half elements
- -- That's why we are marking multiples of 3, 5, 7 (density = 1-(2/3)*(4/5)*(6/7) = 0.543 > 50%)
- for idx = 1, max_idx, 3*5*7 do
- sieve[idx] = true
- sieve[idx + 3] = true
- sieve[idx + 5] = true
- sieve[idx + 6] = true
- sieve[idx + 9] = true
- sieve[idx + 10] = true
- sieve[idx + 12] = true
- sieve[idx + (15 + 0)] = true
- sieve[idx + (3 + 7*2)] = true
- sieve[idx + (15 + 3)] = true
- sieve[idx + (15 + 5)] = true
- sieve[idx + (15 + 6)] = true
- sieve[idx + (15 + 9)] = true
- sieve[idx + (15 + 10)] = true
- sieve[idx + (15 + 12)] = true
- sieve[idx + (15*2 + 0)] = true
- sieve[idx + (3 + 7*4)] = true
- sieve[idx + (15*2 + 3)] = true
- sieve[idx + (15*2 + 5)] = true
- sieve[idx + (15*2 + 6)] = true
- sieve[idx + (3 + 7*5)] = true
- sieve[idx + (15*2 + 9)] = true
- sieve[idx + (15*2 + 10)] = true
- sieve[idx + (15*2 + 12)] = true
- sieve[idx + (15*3 + 0)] = true
- sieve[idx + (15*3 + 3)] = true
- sieve[idx + (15*3 + 5)] = true
- sieve[idx + (15*3 + 6)] = true
- sieve[idx + (3 + 7*7)] = true
- sieve[idx + (15*3 + 9)] = true
- sieve[idx + (15*3 + 10)] = true
- sieve[idx + (15*3 + 12)] = true
- sieve[idx + (3 + 7*8)] = true
- sieve[idx + (15*4 + 0)] = true
- sieve[idx + (15*4 + 3)] = true
- sieve[idx + (15*4 + 5)] = true
- sieve[idx + (15*4 + 6)] = true
- sieve[idx + (15*4 + 9)] = true
- sieve[idx + (15*4 + 10)] = true
- sieve[idx + (15*4 + 12)] = true
- sieve[idx + (3 + 7*10)] = true
- sieve[idx + (15*5 + 0)] = true
- sieve[idx + (15*5 + 3)] = true
- sieve[idx + (15*5 + 5)] = true
- sieve[idx + (15*5 + 6)] = true
- sieve[idx + (15*5 + 9)] = true
- sieve[idx + (15*5 + 10)] = true
- sieve[idx + (15*5 + 12)] = true
- sieve[idx + (15*6 + 0)] = true
- sieve[idx + (15*6 + 3)] = true
- sieve[idx + (3 + 7*13)] = true
- sieve[idx + (15*6 + 5)] = true
- sieve[idx + (15*6 + 6)] = true
- sieve[idx + (15*6 + 9)] = true
- sieve[idx + (15*6 + 10)] = true
- sieve[idx + (3 + 7*14)] = true
- sieve[idx + (15*6 + 12)] = true
- end
- local root_max_number = math.sqrt(max_number) + 0.01
- local factor_idx = -1
- local factor = 11
- repeat
- primes_cnt = primes_cnt + 1
- primes[primes_cnt] = factor
- for idx = (factor * factor - 13) / 2, max_idx, factor do
- sieve[idx] = true
- end
- repeat
- factor_idx = factor_idx + 1
- until not sieve[factor_idx]
- factor = 2 * factor_idx + 13
- until factor > root_max_number
- primes_cnt = primes_cnt + 1
- primes[primes_cnt] = factor
- repeat
- repeat
- factor_idx = factor_idx + 1
- until not sieve[factor_idx]
- primes_cnt = primes_cnt + 1
- primes[primes_cnt] = 2 * factor_idx + 13
- until factor_idx >= max_idx
- return primes
- end
- -- get array of first 100000 primes (it takes 0.13 seconds)
- local primes = get_array_of_primes(1299709)
- ---------------------------------------------
- -- precalculate all G[m] (it takes 0.12 sec)
- local G = {}
- local g = 1
- for k = 1, 100000 do
- local b, s, p, n = 1000000007, primes[k]-1, 0, 1
- while s > 1 do
- local r = b % s
- p, n = n, p + (r - b) / s * n
- b, s = s, r
- end
- local ii = n % 1000000007
- local L = ii % 65536
- local H = (ii - L) / 65536
- g = (H * g % 1000000007 * 65536 + g * L) % 1000000007
- g = (H * g % 1000000007 * 65536 + g * L) % 1000000007
- G[k] = g
- end
- --~ io.input("input.txt")
- -------------------------------------------------------------------------------------
- -- MAIN LOOP
- -------------------------------------------------------------------------------------
- for _ = 1, io.read"*n" do
- local m, a = io.read("*n", "*n")
- local result = G[m] -- this value has already been precalculated
- local a2 = a + 2
- for k = 1, m do
- ------------------------------------------------------------------------
- -- The body of this inner loop is executed up to 3.9 million times
- ------------------------------------------------------------------------
- local p = primes[k] -- this value has already been precalculated
- local ak2 = a2 + k -- 3 <= ak2 < 2^18
- -- Next 16 lines calculate: W = p^ak2
- local exponent = ak2
- local mask = 131072 -- 2^17
- while mask > exponent do
- mask = mask / 2
- end
- exponent = exponent - mask
- local W = p
- while mask > 1 do
- local R = W % 65536
- W = ((W - R) / 65536 * W % 1000000007 * 65536 + W * R) % 1000000007
- mask = mask / 2
- if exponent >= mask then
- exponent = exponent - mask
- W = W * p % 1000000007
- end
- end
- -- Next 3 lines calculate: result = result * (W - 1 - (p - 1) * ak2)
- local W = (W - 1 - (p - 1) * ak2) % 1000000007
- local R = W % 65536
- result = ((W - R) / 65536 * result % 1000000007 * 65536 + result * R) % 1000000007
- ------------------------------------------------------------------------
- end
- print(result)
- end
- --~ print(os.clock())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement