diff --git a/solutions/0050.ConsecutivePrimeSum/euler_50_better.py b/solutions/0050.ConsecutivePrimeSum/euler_50_better.py index 04fd82e..bc85219 100644 --- a/solutions/0050.ConsecutivePrimeSum/euler_50_better.py +++ b/solutions/0050.ConsecutivePrimeSum/euler_50_better.py @@ -10,7 +10,7 @@ Which prime, below one-million, can be written as the sum of the most consecutiv """ import time -from math import isqrt, log +from math import isqrt, log, sqrt from bitarray import bitarray @@ -88,26 +88,31 @@ def is_prime(num: int) -> bool: return True +def get_bound_dynanic(N, iterations=3): + # 初始猜测(基于简化公式) + k = sqrt(2 * N / log(N)) if N > 100 else 10 + + # 牛顿法迭代(3次足够) + for _ in range(iterations): + ln_k = log(k) + # f(k) = k^2 * ln_k - 2N, f'(k) = k * (2*ln_k + 1) + k = (k**2 * (1 + ln_k) + 2 * N) / (k * (2 * ln_k + 1)) + + return int(k) # 返回安全上界(如562) + + def get_bound(limit: int = 10**6) -> int: """ - 使用牛顿法估算筛法所需的素数上限。 + 估算素数个数上限。 """ - - def f(t: float) -> float: - return t**2 * (2 * log(t) - 1) - 2 * limit - - def fp(t: float) -> float: - return 4 * t * log(t) - - x, y = limit, limit + 2 - while y - x > 1: - y, x = x, x - f(x) / fp(x) - return int(x * (log(x) + log(log(x) - 1))) + return int(isqrt(int(2 * limit / log(limit))) * 1.55) +@timer def max_primes_sum_best(limit: int = 10**6) -> tuple[int, int] | None: # === 1. 确定搜索范围 === - bound = get_bound(limit) + bound = get_bound_dynanic(limit) + print(f"bound: {bound}") primes = n_primes(bound) # === 2. 构建前缀和数组 === @@ -157,7 +162,6 @@ def max_primes_sum_best(limit: int = 10**6) -> tuple[int, int] | None: return best_prime, best_length -@timer def main(): limit = int(input("limit:")) max_sum = max_primes_sum_best(limit)