它要求获得斐波那契数 sequence.Can 搞不懂为什么我的代码总是超时
It asks to get a term of Fibonacci sequence.Can't make out why my code always gets timeout
这是 Hackerrank.The 中的一个问题 link 在这里:fibonacci-finding-easy
给出递归序列F(n+2)=F(n+1)+F(n)的两个初值F(0),F(1)分别赋给A,B和要求它的第 N 项,输出它模 (10^9 + 7)。我知道经典的解决方法是使用快速矩阵 multiplication.And 我在 Python3.The 测试中写它 IDE 没有 problems.But 我不知道为什么我的代码总是得到 timeout.Here 是我的代码:
def mul22(a, b):
r = [[0, 0], [0, 0]]
r[0][0] = (a[0][0] * b[0][0] + a[0][1] * b[1][0]) % 1000000007
r[0][1] = (a[0][0] * b[0][1] + a[0][1] * b[1][1]) % 1000000007
r[1][0] = (a[1][0] * b[0][0] + a[1][1] * b[1][0]) % 1000000007
r[1][1] = (a[1][0] * b[0][1] + a[1][1] * b[1][1]) % 1000000007
return r
def MatrixPow(A, n):
if n == 1:
return A
if n % 2 == 1:
return mul22(mul22(MatrixPow(A, n // 2),MatrixPow(A, n // 2)), A)
return mul22(MatrixPow(A, n // 2), MatrixPow(A, n // 2))
for i in range(int(input())):
A,B,N= map(int,input().split())
if N == 1:
print(B % 1000000007)
else:
print(mul22(MatrixPow([[1, 1],[1, 0]], N - 1),[[B,1],[A,1]])[0][0] % 1000000007)
首先我认为问题是 10 ** 9 + 7 进行了整个递归过程所以 slow.But 我在我的 IDE 中测试了很多次并且一切正常,存在没有 TLEs.Is 有什么我错过的吗?
您编写 MatrixPow
函数的方式实际上并不是 O(log(n))
中的 运行。它的 运行 时间是 O(N)
.
考虑这个幂函数:
def power_n(a,b):
print 1
if b==0:
return 1
if b%2==1:
return (((power_n(a,b/2)*power_n(a,b/2))%MOD)*a)%MOD
return (power_n(a,b/2)*power_n(a,b/2))%MOD
还有这个:
def power_log(a,b):
print 2
if b==0:
return 1
k = power_log(a,b/2)
if b%2==1:
return (((k*k)%MOD)*a)%MOD
return (k*k)%MOD
第一种和第二种的区别在于,在第二种情况下我们只遍历整个递归树一次(因为一旦我们有了某个值,我们就保存它)而在第一种情况下,我们一次又一次地计算它.
虽然看起来一样,但第一个类似于传统循环,运行时间为O(n),而第二个函数实际上是幂函数,运行时间为O(log n)
PS:n
表示 b
,即。权力
编辑:
分析:
(我刚刚向函数和 运行 添加了打印语句,这是结果)
power_n(6,20)
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
Out[22]: 414469870
power_log(6,20)
2
2
2
2
2
2
Out[25]: 414469870
查看函数调用次数的差异。
这是 Hackerrank.The 中的一个问题 link 在这里:fibonacci-finding-easy
给出递归序列F(n+2)=F(n+1)+F(n)的两个初值F(0),F(1)分别赋给A,B和要求它的第 N 项,输出它模 (10^9 + 7)。我知道经典的解决方法是使用快速矩阵 multiplication.And 我在 Python3.The 测试中写它 IDE 没有 problems.But 我不知道为什么我的代码总是得到 timeout.Here 是我的代码:
def mul22(a, b):
r = [[0, 0], [0, 0]]
r[0][0] = (a[0][0] * b[0][0] + a[0][1] * b[1][0]) % 1000000007
r[0][1] = (a[0][0] * b[0][1] + a[0][1] * b[1][1]) % 1000000007
r[1][0] = (a[1][0] * b[0][0] + a[1][1] * b[1][0]) % 1000000007
r[1][1] = (a[1][0] * b[0][1] + a[1][1] * b[1][1]) % 1000000007
return r
def MatrixPow(A, n):
if n == 1:
return A
if n % 2 == 1:
return mul22(mul22(MatrixPow(A, n // 2),MatrixPow(A, n // 2)), A)
return mul22(MatrixPow(A, n // 2), MatrixPow(A, n // 2))
for i in range(int(input())):
A,B,N= map(int,input().split())
if N == 1:
print(B % 1000000007)
else:
print(mul22(MatrixPow([[1, 1],[1, 0]], N - 1),[[B,1],[A,1]])[0][0] % 1000000007)
首先我认为问题是 10 ** 9 + 7 进行了整个递归过程所以 slow.But 我在我的 IDE 中测试了很多次并且一切正常,存在没有 TLEs.Is 有什么我错过的吗?
您编写 MatrixPow
函数的方式实际上并不是 O(log(n))
中的 运行。它的 运行 时间是 O(N)
.
考虑这个幂函数:
def power_n(a,b):
print 1
if b==0:
return 1
if b%2==1:
return (((power_n(a,b/2)*power_n(a,b/2))%MOD)*a)%MOD
return (power_n(a,b/2)*power_n(a,b/2))%MOD
还有这个:
def power_log(a,b):
print 2
if b==0:
return 1
k = power_log(a,b/2)
if b%2==1:
return (((k*k)%MOD)*a)%MOD
return (k*k)%MOD
第一种和第二种的区别在于,在第二种情况下我们只遍历整个递归树一次(因为一旦我们有了某个值,我们就保存它)而在第一种情况下,我们一次又一次地计算它.
虽然看起来一样,但第一个类似于传统循环,运行时间为O(n),而第二个函数实际上是幂函数,运行时间为O(log n)
PS:n
表示 b
,即。权力
编辑:
分析: (我刚刚向函数和 运行 添加了打印语句,这是结果)
power_n(6,20)
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
Out[22]: 414469870
power_log(6,20)
2
2
2
2
2
2
Out[25]: 414469870
查看函数调用次数的差异。