对于n个查询,给我一个数字x,我必须以模1000000007打印其阶乘。
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的值的运行时错误。我是否缺少模运算符?
答案 0 :(得分:1)
为什么首先要使用递归来计算简单阶乘?您可以循环查看字典。或更妙的是,从有效的最高记忆位置开始,然后从该位置走高,随行创建新条目。
为节省空间,也许每32次迭代或仅记录一次n!
,所以将来的调用最多需要31次乘法。仍为O(1),但为了节省大量空间而进行了一些计算。
此外,在获得最终的大积之前应用模数是否可行?像每隔几个乘法步骤以保持数字小?或者,如果每个步骤都保持较小的数目,则对于CPython的单臂快速路径而言,它还是足够的。我认为(x * y) % n = ((x%n) * y) % n
。 (但是我没有仔细检查。)
如果是这样,您可以将早期的模与稀疏的记忆结合起来,以记忆最终的模减少结果。
(对于大于2 ^ 30的数字,Python BigInteger乘以成本应按表示该数字所需的2 ^ 30个块的数量进行缩放。幸运的是,被乘数之一始终很小,是计数器。保持产品小的购买速度,