ID photo of Ciro Santilli taken in 2013 right eyeCiro Santilli OurBigBook logoOurBigBook.com  Sponsor 中国独裁统治 China Dictatorship 新疆改造中心、六四事件、法轮功、郝海东、709大抓捕、2015巴拿马文件 邓家贵、低端人口、西藏骚乱
euler/953.py
'''
By GPT-5.1. Runtime: 1.22s on pypy3 3.11.13, Ubuntu 25.10, Lenovo ThinkPad P14s.
'''

import math
from typing import List, Tuple

MOD: int = 10**9 + 7
PRIME_LIMIT: int = 1 << 24

def sieve(limit: int) -> Tuple[bytearray, List[int]]:
    is_prime: bytearray = bytearray(b"\x01") * (limit + 1)
    is_prime[0:2] = b"\x00\x00"
    upper: int = int(limit**0.5)
    for p in range(2, upper + 1):
        if is_prime[p]:
            step: int = p
            start: int = p * p
            is_prime[start:limit+1:step] = b"\x00" * (((limit - start) // step) + 1)
    primes: List[int] = [i for i in range(2, limit + 1) if is_prime[i]]
    return is_prime, primes

is_prime, primes = sieve(PRIME_LIMIT)
INV6: int = pow(6, MOD - 2, MOD)

def sum_sq(T: int) -> int:
    T_mod: int = T % MOD
    return (T_mod * (T_mod + 1) % MOD * (2 * T_mod + 1) % MOD) * INV6 % MOD

def contribution_for_m(m: int, N: int) -> int:
    if m > N:
        return 0
    T: int = math.isqrt(N // m)
    if T == 0:
        return 0
    return (m % MOD) * sum_sq(T) % MOD

def compute_S(N: int) -> int:
    ans: int = contribution_for_m(1, N) % MOD
    sqrtN: int = math.isqrt(N)
    prefix_end: int = 0
    for i, p in enumerate(primes):
        if p > sqrtN:
            break
        prefix_end = i + 1
    stack: List[Tuple[int, int, int, int]] = []
    for idx in range(prefix_end):
        p: int = primes[idx]
        if p * p > N:
            break
        stack.append((idx + 1, p, p, p))
    primes_local: List[int] = primes
    is_prime_local: bytearray = is_prime
    PRIME_LIMIT_LOCAL: int = PRIME_LIMIT
    N_local: int = N
    while stack:
        next_idx, prod, xor_val, last_p = stack.pop()
        cand: int = xor_val
        if cand > last_p and cand <= PRIME_LIMIT_LOCAL and is_prime_local[cand] and prod * cand <= N_local:
            m: int = prod * cand
            ans = (ans + contribution_for_m(m, N_local)) % MOD
        N_div_prod: int = N_local // prod
        for j in range(next_idx, prefix_end):
            q: int = primes_local[j]
            if q * q > N_div_prod:
                break
            new_prod: int = prod * q
            new_xor: int = xor_val ^ q
            stack.append((j + 1, new_prod, new_xor, q))
    return ans % MOD

if __name__ == "__main__":
    assert compute_S(10) == 14
    assert compute_S(100) == 455
    print(compute_S(10**14) % MOD)