def fast_S(n): # Every number after the first 15 will just be some number of copies of 123432 and then the digits given in the cycle of 15 sum. # So split this number into the 123432 parts and the cycle of 15 parts. total = fifteen_cycle_sum(n) # Now we have to account for the copies of 123432. num_full_cycles = n / 15 num_full_cycles_expr = Num(num_full_cycles) partial_cycle = n % 15 if num_full_cycles > 0 and partial_cycle != 0: # For each number in multipliers, this adds a 123432(1 + 10^6 + 10^12 + ... + 10^(6 * num_full_cycles)) amount. # this sums to 123432 * modinv(10^6 - 1) * (10^(6 * num_full_cycles - 6) - 1). large_power_expr = Exp(Num(10), Mult(Num(6), num_full_cycles_expr)) # print 'doing partial cycle stuff' for i in range(1, partial_cycle + 1): # print get_a(i) + 10**6 * get_a(i) total += get_a(i) * modinv(10**6 - 1, modulus) * (large_power_expr.compute_value(modulus) - 1) % modulus if num_full_cycles > 1: ''' Mathematica blesses me by summing the shitty geometric series.''' r = 10**6 total += sum([get_a(k) for k in range(1, 16)]) * modinv((r - 1)**2, modulus) * (Exp(Num(10**6), num_full_cycles_expr).compute_value(modulus) - 1 - (r - 1) * num_full_cycles) return total % modulus
def fast_S(n): # Every number after the first 15 will just be some number of copies of 123432 and then the digits given in the cycle of 15 sum. # So split this number into the 123432 parts and the cycle of 15 parts. total = fifteen_cycle_sum(n) # Now we have to account for the copies of 123432. num_full_cycles = n / 15 num_full_cycles_expr = Num(num_full_cycles) partial_cycle = n % 15 if num_full_cycles > 0 and partial_cycle != 0: # For each number in multipliers, this adds a 123432(1 + 10^6 + 10^12 + ... + 10^(6 * num_full_cycles)) amount. # this sums to 123432 * modinv(10^6 - 1) * (10^(6 * num_full_cycles - 6) - 1). large_power_expr = Exp(Num(10), Mult(Num(6), num_full_cycles_expr)) # print 'doing partial cycle stuff' for i in range(1, partial_cycle + 1): # print get_a(i) + 10**6 * get_a(i) total += get_a(i) * modinv(10**6 - 1, modulus) * ( large_power_expr.compute_value(modulus) - 1) % modulus if num_full_cycles > 1: ''' Mathematica blesses me by summing the shitty geometric series.''' r = 10**6 total += sum([get_a(k) for k in range(1, 16)]) * modinv( (r - 1)**2, modulus) * (Exp(Num( 10**6), num_full_cycles_expr).compute_value(modulus) - 1 - (r - 1) * num_full_cycles) return total % modulus
def binom(n, k, modulus): result = 1 for i in range(n, n - k, -1): result *= i result %= modulus for i in range(1, k + 1): result *= modinv(i, modulus) result %= modulus return result
def fast_sum_of_M(n): reduced_n = n % (6 * 7**8) return (modinv(3, modulus) * (pow(4, reduced_n + 1, modulus) - 1) + 2 * (pow(2, reduced_n + 1, modulus) - 1) - modinv(2, modulus) * (pow(3, reduced_n + 1, modulus) - 1)) % modulus
x_coeff = Fraction(1) const_coeff = Fraction(0) while len(seq) > 0: next_elem = seq.pop() if next_elem == 'U': x_coeff *= Fraction(4, 3) const_coeff = const_coeff * Fraction(4, 3) + Fraction(2, 3) elif next_elem == 'd': x_coeff *= Fraction(2, 3) const_coeff = const_coeff * Fraction(2, 3) - Fraction(1, 3) else: x_coeff *= Fraction(1, 3) const_coeff *= Fraction(1, 3) print x_coeff print const_coeff modulus = x_coeff.denominator a = x_coeff.numerator b = const_coeff.numerator x = (-b) * modinv(a, modulus) % modulus print modinv(a, modulus) answer = x while answer < 10 ** 15: answer += modulus print answer
high_limit = 10**7 + 10**4 for candidate in range(low_limit, high_limit): if isPrimeMR(candidate): primes.append(candidate) print 'primes found, there are %s of them ' % len(primes) k_facts = [1] + [0] * (high_limit - 1) cumprod = 1 for k in range(1, high_limit): cumprod *= k cumprod %= modulus k_facts[k] = cumprod k_facts_invs = [modinv(k, modulus) for k in k_facts] def binom(n, k, modulus): if n < 0 or k < 0 or k > n: return 0 if k > n - k: return binom(n, n - k, modulus) return (k_facts[n] * k_facts_invs[k] * k_facts_invs[n - k]) % modulus def G(n, modulus): n_sq = sqrt(n) b = 0
def compute_answer(): total = 0 current_coeff_pf = defaultdict(lambda : 0) current_coeff = 1 current_r = 1 for k in range(1, (n + 1) / 2 + 1): if k % 10000 == 0: print k, (n + 1) / 2 current_coeff *= (n - k + 1) current_coeff *= modinv(k, modulus) current_coeff %= modulus required_mult_num = 1 required_mult_den = 1 for prime, power in get_pf(n - k + 1).items(): old_power = current_coeff_pf[prime] current_coeff_pf[prime] += power new_power = old_power + power required_mult_num *= pow(prime, new_power, modulus) + 1 required_mult_num %= modulus assert new_power >= 0 if new_power < 0: print 'hi' print n - k + 1, get_pf(n - k + 1), new_power if old_power > 0: required_mult_den *= pow(prime, old_power, modulus) + 1 required_mult_den %= modulus for prime, power in get_pf(k).items(): # print k, get_pf(k) old_power = current_coeff_pf[prime] current_coeff_pf[prime] -= power new_power = old_power - power if new_power < 0: print k, get_pf(k), old_power if new_power > 0: required_mult_num *= pow(prime, new_power, modulus) + 1 required_mult_num %= modulus required_mult_den *= pow(prime, old_power, modulus) + 1 required_mult_den %= modulus if current_coeff_pf[prime] == 0: del current_coeff_pf[prime] # print required_mult_num, required_mult_den, modinv(required_mult_den, modulus) * required_mult_den % modulus current_r *= required_mult_num * modinv(required_mult_den, modulus) current_r %= modulus total += 2 * (current_r - current_coeff) total %= modulus # print k, current_r - current_coeff, current_coeff #, total, current_coeff # print k total -= (current_r - current_coeff) total %= modulus return total
from math import sqrt limit = 10**14 modulus = 982451653 # print 1683550844462 % modulus max_k = int(sqrt(2 * limit)) while (max_k + 1) * (max_k + 4) / 2 > limit: max_k -= 1 remainder = limit - (max_k + 1) * (max_k + 4) / 2 print max_k, remainder total = 1 current_inverse_sum = modinv(2, modulus) modinv2 = modinv(2, modulus) current_product = 2 for k in range(1, max_k + 1): if k % 10**6 == 0: print k current_product *= (k + 2) current_product %= modulus modinvk2 = modinv(k + 2, modulus) current_inverse_sum += modinvk2 current_inverse_sum %= modulus # Current product now contains 2 * 3 * ... * (k + 2). # Current inverse sum now contains (1/2 + 1/3 + ... + 1/(k+2)) total += k * current_inverse_sum * current_product # Also need to add the 3, 4, 5, ..., k + 1, k + 3 partition.
Observation says it's the coefficient on x^d on sum_{i = 0}^{m-1} (n choose i) (x-1)^i Mathematica tells me this is (up to absolute value) equal to (m-d) / (n-d) * (m choose d) * (n choose d) ''' from helpers import modinv modulus = 999999937 n = 10**13 m = 10**12 d = 10**4 answer = m - d answer *= modinv(n - d, modulus) def binom(n, k, modulus): result = 1 for i in range(n, n - k, -1): result *= i result %= modulus for i in range(1, k + 1): result *= modinv(i, modulus) result %= modulus return result answer *= binom(m, d, modulus) * binom(n % modulus, m % modulus,
Observation says it's the coefficient on x^d on sum_{i = 0}^{m-1} (n choose i) (x-1)^i Mathematica tells me this is (up to absolute value) equal to (m-d) / (n-d) * (m choose d) * (n choose d) ''' from helpers import modinv modulus = 999999937 n = 10**13 m = 10**12 d = 10**4 answer = m - d answer *= modinv(n - d, modulus) def binom(n, k, modulus): result = 1 for i in range(n, n - k, -1): result *= i result %= modulus for i in range(1, k + 1): result *= modinv(i, modulus) result %= modulus return result answer *= binom(m, d, modulus) * binom(n % modulus, m % modulus, modulus) * binom(n / modulus, m / modulus, modulus) answer %= modulus