50题解决了,使用了动态上限,优化了搜索。

This commit is contained in:
2026-03-17 17:52:50 +08:00
parent 3358e97dd4
commit f6f88a9e9d

View File

@@ -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)