#!/usr/bin/env python3 # Generated by GPT-5 on 2025-11-05. Tested on Ubuntu 25.04, pypy3 3.11.11. Runtime on Lenovo ThinkPad P14s: 0m0.077s # Output: 412543690 # Computes sum_{n=1..N} S(n) for Project Euler 969 formulation, modulo 1e9+7. # N is set to 10**18 per problem statement. # This script is self-contained and uses Python's big integers. MOD = 10**9 + 7 def primes_upto(n): sieve = bytearray(b"\x01") * (n+1) primes = [] for i in range(2, n+1): if sieve[i]: primes.append(i) step = i start = i*i if start > n: continue sieve[start:n+1:step] = b"\x00" * (((n - start)//step) + 1) return primes def sum_pows_lagrange(T, k, MOD): # returns sum_{t=1}^T t^k mod MOD using Lagrange interpolation on points 0..d (d=k+1) d = k + 1 if T <= d: s = 0 for i in range(1, T+1): s = (s + pow(i, k, MOD)) % MOD return s # y_i = sum_{t=1}^i t^k for i=0..d ys = [0] * (d + 1) for i in range(1, d + 1): ys[i] = (ys[i-1] + pow(i, k, MOD)) % MOD fact = [1] * (d + 1) for i in range(1, d + 1): fact[i] = fact[i-1] * i % MOD invfact = [1] * (d + 1) invfact[d] = pow(fact[d], MOD-2, MOD) for i in range(d, 0, -1): invfact[i-1] = invfact[i] * i % MOD Tmod = T % MOD # pre[i] = prod_{j=0..i-1} (T - j) pre = [1] * (d + 1) for i in range(1, d + 1): pre[i] = pre[i-1] * (Tmod - (i-1)) % MOD # suf[i] = prod_{j=i+1..d} (T - j) => we build suf with one extra slot suf = [1] * (d + 2) for i in range(d, -1, -1): suf[i] = suf[i+1] * (Tmod - i) % MOD res = 0 # Lagrange basis for x_i = i, i=0..d for i in range(0, d + 1): # numerator = pre[i] * suf[i+1] = prod_{j != i} (T - j) num = pre[i] * suf[i+1] % MOD # denom = ∏_{j != i} (i - j) = (-1)^{d-i} * i! * (d-i)! denom = fact[i] * fact[d - i] % MOD if ((d - i) & 1) == 1: denom = (-denom) % MOD invden = pow(denom, MOD-2, MOD) li = num * invden % MOD res = (res + ys[i] * li) % MOD return res def compute_Mk(k, primes): # compute M_k = ∏_{p <= k} p^{ceil(v_p(k!)/k)} if k == 0: return 1 M = 1 for p in primes: if p > k: break v = 0 pp = p # v_p(k!) while pp <= k: v += k // pp pp *= p e = (v + k - 1) // k # ceil(v/k) if e > 0: M *= pow(p, e) return M def compute_sum_S_upto_N(N): primes = primes_upto(1000) # plenty for our k range MOD = 10**9 + 7 # precompute factorials (for modular inverses) up to a safe bound MAXF = 200 fact = [1] * (MAXF + 1) for i in range(1, MAXF + 1): fact[i] = fact[i-1] * i % MOD total = 0 k = 0 while True: M = compute_Mk(k, primes) if k > 0 else 1 if M > N: break if k == 0: T = N # m runs over 1..N (since M_0 = 1) else: if N < k: break T = (N - k) // M if T <= 0: k += 1 continue # C_k = (-1)^k * M^k / k! (mod MOD) if k == 0: C = 1 else: C = pow(M % MOD, k, MOD) * pow(fact[k], MOD-2, MOD) % MOD if k & 1: C = (-C) % MOD sum_tk = sum_pows_lagrange(T, k, MOD) contrib = C * sum_tk % MOD total = (total + contrib) % MOD k += 1 return total if __name__ == "__main__": N = 10**18 print(compute_sum_S_upto_N(N) % MOD)