Qwen 3.5plus编写的求解欧拉计划901题python程序优化

翻译版原题如下,取自:https://pe-cn.github.io/902/

第一版

python 复制代码
def factorial(n):
    """计算n的阶乘"""
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

def rank(perm):
    """
    计算置换perm的rank(字典序位置,从1开始)
    perm是一个列表,perm[i]表示位置i+1的值
    """
    n = len(perm)
    r = 1  # rank从1开始
    
    for i in range(n):
        # 计算在位置i,有多少个未使用的数小于perm[i]
        count = 0
        for j in range(i + 1, n):
            if perm[j] < perm[i]:
                count += 1
        r += count * factorial(n - i - 1)
    
    return r

def compute_sigma(m):
    """
    计算σ置换
    n = m(m+1)/2
    σ(i) = k(k-1)/2 + 1  如果存在k使得i = k(k+1)/2
    σ(i) = i + 1         其他情况
    """
    n = m * (m + 1) // 2
    sigma = [0] * (n + 1)  # 1-indexed
    
    # 标记特殊位置
    special_positions = set()
    for k in range(1, m + 1):
        pos = k * (k + 1) // 2
        special_positions.add(pos)
    
    for i in range(1, n + 1):
        if i in special_positions:
            # 找到k使得i = k(k+1)/2
            for k in range(1, m + 1):
                if i == k * (k + 1) // 2:
                    sigma[i] = k * (k - 1) // 2 + 1
                    break
        else:
            sigma[i] = i + 1
    
    return sigma[1:]  # 返回0-indexed列表

def compute_tau(n):
    """
    计算τ置换
    τ(i) = ((10^9 + 7) * i mod n) + 1
    """
    MOD_BASE = 10**9 + 7
    tau = [0] * (n + 1)  # 1-indexed
    
    for i in range(1, n + 1):
        tau[i] = ((MOD_BASE * i) % n) + 1
    
    return tau[1:]  # 返回0-indexed列表

def compute_inverse(perm):
    """计算置换perm的逆置换"""
    n = len(perm)
    inv = [0] * n
    for i in range(n):
        inv[perm[i] - 1] = i + 1  # perm是1-indexed的值
    return inv

def compute_pi(m):
    """
    计算π置换
    π(i) = τ^(-1)(σ(τ(i)))
    """
    n = m * (m + 1) // 2
    
    sigma = compute_sigma(m)
    tau = compute_tau(n)
    tau_inv = compute_inverse(tau)
    
    # π(i) = τ^(-1)(σ(τ(i)))
    # 注意:sigma, tau, tau_inv都是0-indexed列表,但存储的是1-indexed的值
    pi = [0] * n
    for i in range(n):
        # i是0-indexed的位置,对应1-indexed的i+1
        tau_i = tau[i]  # τ(i+1),这是1-indexed的值
        sigma_tau_i = sigma[tau_i - 1]  # σ(τ(i+1))
        pi[i] = tau_inv[sigma_tau_i - 1]  # τ^(-1)(σ(τ(i+1)))
    
    return pi

def compose_permutations(p1, p2):
    """
    计算置换的复合 p1 ∘ p2
    即先应用p2,再应用p1
    """
    n = len(p1)
    result = [0] * n
    for i in range(n):
        # p2[i]是位置i+1映射到的值(1-indexed)
        # 需要在p1中找到这个值对应的位置
        result[i] = p1[p2[i] - 1]
    return result

def power_permutation(perm, k):
    """计算置换perm的k次幂"""
    n = len(perm)
    if k == 0:
        return list(range(1, n + 1))  # 恒等置换
    
    result = list(range(1, n + 1))  # 恒等置换
    base = perm[:]
    
    while k > 0:
        if k % 2 == 1:
            result = compose_permutations(base, result)
        base = compose_permutations(base, base)
        k //= 2
    
    return result

def compute_P(m):
    """
    计算P(m) = Σ(k=1 to m!) rank(π^k)
    """
    n = m * (m + 1) // 2
    pi = compute_pi(m)
    
    total = 0
    m_fact = factorial(m)
    
    # 计算π的幂
    pi_power = list(range(1, n + 1))  # 初始为恒等置换
    
    for k in range(1, m_fact + 1):
        pi_power = compose_permutations(pi, pi_power)
        r = rank(pi_power)
        total += r
        if k <= 3 or k == m_fact:  # 只显示前几个和最后一个
            print(f"  k={k}: rank={r}")
    
    return total

# 验证例子
"""
print("验证例子:")
print("rank([2,1,3]) =", rank([2, 1, 3]))
print("期望值:3")
print()

print("计算P(2):")
p2 = compute_P(2)
print(f"P(2) = {p2}")
print(f"期望值:4")
print(f"匹配:{p2 == 4}")
print()

print("计算P(3):")
p3 = compute_P(3)
print(f"P(3) = {p3}")
print(f"期望值:780")
print(f"匹配:{p3 == 780}")
print()

print("计算P(4):")
p4 = compute_P(4)
print(f"P(4) = {p4}")
print(f"期望值:38810300")
print(f"匹配:{p4 == 38810300}")
"""
print("计算P(10):")
p10 = compute_P(10)
print(f"P(10) = {p10}")

优化版

python 复制代码
import math
from math import gcd

MOD = 10**9 + 7

def factorial_mod(n, mod):
    """计算n! mod mod"""
    result = 1
    for i in range(2, n + 1):
        result = (result * i) % mod
    return result

def factorial(n):
    """计算n的阶乘(完整值)"""
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

def rank_mod(perm, mod):
    """
    计算置换perm的rank(字典序位置,从1开始),并对mod取模
    使用优化的算法,边计算边取模
    """
    n = len(perm)
    r = 1  # rank从1开始
    
    # 预计算阶乘
    facts = [1] * (n + 1)
    for i in range(1, n + 1):
        facts[i] = (facts[i-1] * i) % mod
    
    for i in range(n):
        # 计算在位置i,有多少个未使用的数小于perm[i]
        count = 0
        for j in range(i + 1, n):
            if perm[j] < perm[i]:
                count += 1
        r = (r + count * facts[n - i - 1]) % mod
    
    return r

def compute_sigma(m):
    """
    计算σ置换
    n = m(m+1)/2
    σ(i) = k(k-1)/2 + 1  如果存在k使得i = k(k+1)/2
    σ(i) = i + 1         其他情况
    """
    n = m * (m + 1) // 2
    sigma = [0] * (n + 1)  # 1-indexed
    
    # 标记特殊位置
    special_positions = set()
    for k in range(1, m + 1):
        pos = k * (k + 1) // 2
        special_positions.add(pos)
    
    for i in range(1, n + 1):
        if i in special_positions:
            # 找到k使得i = k(k+1)/2
            for k in range(1, m + 1):
                if i == k * (k + 1) // 2:
                    sigma[i] = k * (k - 1) // 2 + 1
                    break
        else:
            sigma[i] = i + 1
    
    return sigma[1:]  # 返回0-indexed列表

def compute_tau(n):
    """
    计算τ置换
    τ(i) = ((10^9 + 7) * i mod n) + 1
    """
    MOD_BASE = 10**9 + 7
    tau = [0] * (n + 1)  # 1-indexed
    
    for i in range(1, n + 1):
        tau[i] = ((MOD_BASE * i) % n) + 1
    
    return tau[1:]  # 返回0-indexed列表

def compute_inverse(perm):
    """计算置换perm的逆置换"""
    n = len(perm)
    inv = [0] * n
    for i in range(n):
        inv[perm[i] - 1] = i + 1  # perm是1-indexed的值
    return inv

def compute_pi(m):
    """
    计算π置换
    π(i) = τ^(-1)(σ(τ(i)))
    """
    n = m * (m + 1) // 2
    
    sigma = compute_sigma(m)
    tau = compute_tau(n)
    tau_inv = compute_inverse(tau)
    
    # π(i) = τ^(-1)(σ(τ(i)))
    pi = [0] * n
    for i in range(n):
        tau_i = tau[i]  # τ(i+1),这是1-indexed的值
        sigma_tau_i = sigma[tau_i - 1]  # σ(τ(i+1))
        pi[i] = tau_inv[sigma_tau_i - 1]  # τ^(-1)(σ(τ(i+1)))
    
    return pi

def compose_permutations(p1, p2):
    """
    计算置换的复合 p1 ∘ p2
    即先应用p2,再应用p1
    """
    n = len(p1)
    result = [0] * n
    for i in range(n):
        result[i] = p1[p2[i] - 1]
    return result

def get_cycle_lengths(perm):
    """
    获取置换的循环分解中各个循环的长度
    """
    n = len(perm)
    visited = [False] * n
    cycle_lengths = []
    
    for i in range(n):
        if not visited[i]:
            length = 0
            j = i
            while not visited[j]:
                visited[j] = True
                j = perm[j] - 1  # perm[j]是1-indexed的值
                length += 1
            cycle_lengths.append(length)
    
    return cycle_lengths

def compute_permutation_order(perm):
    """
    计算置换的阶(order)
    阶是所有循环长度的最小公倍数
    """
    cycle_lengths = get_cycle_lengths(perm)
    order = 1
    for length in cycle_lengths:
        order = lcm(order, length)
    return order

def lcm(a, b):
    """计算最小公倍数"""
    return a * b // gcd(a, b)

def compute_P_optimized(m):
    """
    计算P(m) = Σ(k=1 to m!) rank(π^k) mod (10^9 + 7)
    利用置换的周期性进行优化
    """
    n = m * (m + 1) // 2
    pi = compute_pi(m)
    
    # 计算π的阶
    order = compute_permutation_order(pi)
    print(f"置换π的阶: {order}")
    
    # 计算m!
    m_fact = factorial(m)
    print(f"m! = {m_fact}")
    
    # 计算一个周期内的rank和
    print(f"计算一个周期内的rank和(需要计算{order}次)...")
    cycle_sum = 0
    pi_power = list(range(1, n + 1))  # 初始为恒等置换
    
    # 只计算前几个用于验证
    for k in range(1, min(order, 4) + 1):
        pi_power = compose_permutations(pi, pi_power)
        r = rank_mod(pi_power, MOD)
        cycle_sum = (cycle_sum + r) % MOD
        print(f"  k={k}: rank mod (10^9+7) = {r}")
    
    # 如果order很小,计算完整的周期和
    if order <= 10000:
        for k in range(4, order):
            pi_power = compose_permutations(pi, pi_power)
            r = rank_mod(pi_power, MOD)
            cycle_sum = (cycle_sum + r) % MOD
    else:
        # 如果order很大,需要继续计算(这里可能需要更长时间的计算)
        print(f"  警告:阶{order}很大,继续计算可能需要较长时间...")
        for k in range(4, order):
            pi_power = compose_permutations(pi, pi_power)
            r = rank_mod(pi_power, MOD)
            cycle_sum = (cycle_sum + r) % MOD
            if k % 100000 == 0:
                print(f"    已计算到k={k}")
    
    print(f"一个周期内的rank和: {cycle_sum}")
    
    # 计算P(m)
    # P(m) = (m!/order) * cycle_sum + 剩余部分
    quotient = m_fact // order
    remainder = m_fact % order
    
    print(f"m! / order = {quotient}, 余数 = {remainder}")
    
    # 计算剩余部分
    remaining_sum = 0
    if remainder > 0:
        print(f"计算剩余{remainder}项...")
        pi_power = list(range(1, n + 1))
        for k in range(1, remainder + 1):
            pi_power = compose_permutations(pi, pi_power)
            r = rank_mod(pi_power, MOD)
            remaining_sum = (remaining_sum + r) % MOD
    
    # P(m) = quotient * cycle_sum + remaining_sum
    result = (quotient % MOD * cycle_sum % MOD + remaining_sum) % MOD
    
    return result

# 验证例子
"""
print("=" * 60)
print("验证例子:")
print("rank([2,1,3]) =", rank_mod([2, 1, 3], MOD))
print("期望值:3")
print()

print("=" * 60)
print("计算P(2):")
p2 = compute_P_optimized(2)
print(f"P(2) = {p2}")
print(f"期望值:4")
print(f"匹配:{p2 == 4}")
print()

print("=" * 60)
print("计算P(3):")
p3 = compute_P_optimized(3)
print(f"P(3) = {p3}")
print(f"期望值:780")
print(f"匹配:{p3 == 780}")
print()

print("=" * 60)
print("计算P(4):")
p4 = compute_P_optimized(4)
print(f"P(4) = {p4}")
print(f"期望值:38810300")
print(f"匹配:{p4 == 38810300}")
"""

print("计算P(10):")
p10 = compute_P_optimized(10)
print(f"P(14) = {p10}")

里题目要求的p(100)还很远,但理解力和正确性、简单的优化能力都不错了。

相关推荐
no_work2 小时前
基于python的hog+svm实现混凝土裂缝目标检测
人工智能·python·目标检测·计算机视觉
小陈工2 小时前
2026年3月21日技术资讯洞察:云原生理性回归与Python异步革命
人工智能·python·云原生·数据挖掘·回归
追烽少年x2 小时前
在Python中学习OpenCV - ROI(region of interest)
python·opencv
T0uken2 小时前
【Python】docxnote:优雅的 Word 批注
开发语言·python·word
9稳2 小时前
基于智能巡检机器人与PLC系统联动控制设计
开发语言·网络·数据库·嵌入式硬件·plc
B站计算机毕业设计之家2 小时前
计算机毕业设计源码:Python图书数据智能采集与可视化大屏 当当网 Django框架 爬虫 Pandas 可视化 大数据 大模型 书籍(建议收藏)✅
爬虫·python·机器学习·信息可视化·django·pandas·课程设计
承渊政道2 小时前
C++学习之旅【IO库相关内容介绍】
c语言·开发语言·c++·学习·macos·visual studio
维度攻城狮2 小时前
AI 工具加持:ComfyUI 节点开发极速上手
人工智能·python·comfyui·工作流·节点图
Shine_1804182 小时前
ClaudeCode启动报错
python