def f(n):
Total_Triangles = 0
for i in range(1,n+1):
term = 3**(i-1)
Total_Triangles+=term
return Total_Triangles
Q = int(input())
for i in range(Q):
n = int(input())
Ans = f(n)*4 +1
print(Ans%1000000007)
如何处理此代码中的时间限制错误?
答案 0 :(得分:2)
Karan有一个很好的答案。它会加快你原来的方法,但你仍然最终计算出巨大的数字。幸运的是,Python的Long类型可以做到这一点,但我希望它不像本机32位或64位整数类型那样高效。
你被告知给出一个巨大数字M,1,000,000,007的答案。您可以在整个过程中使用modular arithmetic来改进算法,这样您的数字就不会变得非常大。在模运算中,这是真的:
(a + b) % M == (a % M + b % M) % M
(a * b) % M == (a % M * b % M) % M
一种方法可能是使用模运算预先计算所有可能的Q值:
M = 1000000007
def makef(m):
"""Generator to create all sum(3**i) mod M"""
n = 1
s = 0
for i in range(m):
yield s
s = (s + n) % M
n = ((n + n) % M + n) % M
f = list(makef(100000))
Q = int(input())
for i in range(Q):
n = int(input())
print (f[n] * 4 + 1) % M
这将在一个大循环中进行计算,但只进行一次,并且应该足够快以满足您的要求。
Python为您提供了第二种方式:表达式a ** b
映射到内置函数pow(a, b)
。此函数可以采用第三个参数:模块化算术的基础,以便pow(a, b, M)
计算(a ** b) % M
而不会产生巨大的中间结果。
现在你可以使用Karan的整洁配方。但等等,有一个陷阱:你必须将权力的结果除以2。上面的模块化关系不适用于除法。例如,(12 // 2) % M
为6,但如果您首先应用模运算符,正如pow
函数所做的那样,您将获得((12 % 2) // 2) % M
,这是1而不是您想要的。一种解决方案是计算功率模2 * M
,然后除以2:
def f(n):
return pow(3, n, 2 * 1000000007) // 2
Q = int(input())
for i in range(Q):
n = int(input())
print (f(n) * 4 + 1) % M
(注意3的所有幂都是奇数,所以我删除了- 1
并让整数除法完成工作。)
旁注:选择M
的值,以便添加两个小于M
的数字符合带符号的32位整数。这意味着C,C ++或Java的用户不必使用bignum库。但请注意,3 * n
仍然可以溢出已签名的int,因此在乘以3时必须小心:改为使用((n + n) % M + n) % M
。
答案 1 :(得分:1)
您想要找到3 ** 0 + 3 ** 1 ... + 3 ** (n - 1)
,这只是一个几何系列,包含第一项a = 1
,公共比率r = 3
和条件数n = n
,并使用一个几何系列公式,我们可以更快地找到f(n)
,如下所示:
def f(n):
return (3 ** n - 1) // 2