Dictionary 字典与大数的阶乘

Dictionary 字典与大数的阶乘,dictionary,optimization,dynamic-programming,memoization,micro-optimization,Dictionary,Optimization,Dynamic Programming,Memoization,Micro Optimization,对于n个查询,我得到一个数字x,我必须在模100000007下打印它的阶乘。 def fact_eff(n, d): if n in d: return d[n] else: ans=n*fact_eff(n-1,d) d[n]=ans return ans d={0:1} n=int(input()) while(n!=0): x=int(input()) print(fact_eff(x, d

对于n个查询,我得到一个数字x,我必须在模100000007下打印它的阶乘。

def fact_eff(n, d):

    if n in d:
        return d[n]
    else:
        ans=n*fact_eff(n-1,d)
        d[n]=ans
        return ans

d={0:1}
n=int(input())
while(n!=0):
    x=int(input())
    print(fact_eff(x, d)%1000000007)
    n=n-1

问题是x可能大到100000,当最大递归深度超过3000时,我会收到大于3000的运行时错误。我是否缺少模运算符?

为什么要首先使用递归来计算简单的阶乘?你可以循环检查字典。或者更好的办法是,从最高有效的记忆位置开始,然后再往上走,边走边创建新条目

为了节省空间,可能只记录
n每32次迭代或其他,因此未来的调用最多需要31次乘法。仍然是O(1),但为了节省大量空间,需要进行一些计算

另外,在你得到最终的巨大产品之前,应用模量是否有效?像每隔几步乘法来保持数字小?或者每一步,如果这能保持足够小的数值,以满足CPython的单肢快速路径。我认为
(x*y)%n=((x%n)*y)%n
。(但我没有仔细检查。)

如果是这样,您可以将早期模与稀疏记忆结合起来,以记忆最终的模缩减结果

(对于2^30以上的数字,Python BigInteger乘法成本应与表示该数字所需的2^30块的数量成比例。幸运的是,被乘数中的一个总是小的,即计数器。保持乘积小可以提高速度,但除法很昂贵,因此这是一种折衷。而且,进行任何其他操作都需要Python解释器的成本。)rhead可能会一直占据主导地位,直到数量变得非常庞大。)