Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local sqrt = math.sqrt
- -- array of primes
- local primes = setmetatable({2, 3, 5}, {__index =
- function(t, k)
- local p = t[#t]
- for k = #t + 1, k do
- repeat
- p = p + 4 * p % 6
- local i, root, is_compound = 2, sqrt(p) - 1.5
- repeat
- i = i + 1
- local pp = t[i]
- is_compound = p % pp == 0
- until is_compound or root < pp
- until not is_compound
- t[k] = p
- end
- return p
- end
- })
- local _ = primes[100000] -- precalculate all p_k (it takes 1.2 seconds)
- local function Z_inv(value) -- -- 0 <= value < 1000000007
- -- returns value^(-1) mod 1000000007
- -- returns nothing if value = 0
- local b, s, p, n = 1000000007, value, 0, 1
- while s > 1 do
- local r = b % s
- p, n = n, p + (r - b) / s * n
- b, s = s, r
- end
- if s == 1 then
- return n % 1000000007
- end
- end
- local function Z_mul(A, B) -- 0 <= A, B < 1000000007
- local R = B % 65536
- return ((B - R) / 65536 * A % 1000000007 * 65536 + A * R) % 1000000007
- end
- local G = setmetatable({[0] = 1}, {__index =
- function(t, k)
- local g = t[#t]
- for k = #t + 1, k do
- local ii = Z_inv(primes[k]-1)
- g = Z_mul(g, Z_mul(ii, ii))
- t[k] = g
- end
- return g
- end
- })
- local _ = G[100000] -- precalculate all G[m] (it takes only 0.15 sec)
- --~ io.input("input.txt")
- -------------------------------------------------------------------------------------
- -- MAIN LOOP
- -------------------------------------------------------------------------------------
- -- We have 10+ seconds remaining for the following loop
- for _ = 1, io.read"*n" do
- local m, a = io.read("*n", "*n")
- local result = G[m] -- this value has already been precalculated
- for k = 1, m do
- ------------------------------------------------------------------------
- -- The body of this inner loop is executed up to 3.9 million times
- -- I need to increase its speed by 11% to pass all test cases
- -- But I don't know how optimize it more
- ------------------------------------------------------------------------
- local p = primes[k] -- this value has already been precalculated
- local ak2 = a + k + 2 -- 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