1303. 斐波那契前 n 项和

摘要
Title: 1303. 斐波那契前 n 项和
Tag: 斐波那契、矩阵快速幂、快速倍增法
Memory Limit: 64 MB
Time Limit: 1000 ms

Powered by:NEFU AB-IN

Link

1303. 斐波那契前 n 项和

  • 题意

    大家都知道 Fibonacci 数列吧,f1=1,f2=1,f3=2,f4=3,…,fn=fn−1+fn−2。
    现在问题很简单,输入 n 和 m,求 fn 的前 n 项和 Sn mod m。

  • 思路

    求斐波那契的几种方法:Link

    • 方法1
      矩阵快速幂 复杂度 O(logN)O(logN)

      用来构造矩阵,求特殊值

      1303

    • 方法2
      快速倍增法 复杂度 O(logN)O(logN)

      用来求斐波那契的第nn项,这里可以结合 斐波那契的关系,来求解

      Given F(k)F(k) and F(k+1)F(k+1), we can calculate these:

      F(2k)=F(k)[2F(k+1)F(k)]F(2k+1)=F(k)2+F(k+1)2.F(2k)=F(k) * [2*F(k+1)-F(k)] \\ F(2k+1)=F(k)^2+F(k+1)^2.

      定理:

      Sn=fn+2f2=fn+21S_n = f_{n + 2} - f_{2} = f_{n + 2} - 1

  • 代码

    • 矩阵快速幂

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      '''
      Author: NEFU AB-IN
      Date: 2022-04-04 16:00:36
      FilePath: \ACM\Acwing\1303.py
      LastEditTime: 2022-04-04 16:43:32
      '''
      M = 3
      Matrix = lambda: [[0] * M for _ in range(M)]


      def mul(a, b):
      c = Matrix()
      for i in range(M):
      for j in range(M):
      for k in range(M):
      c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % m
      return c


      def quickpow(a, b):
      I = Matrix() #单位矩阵
      for i in range(M):
      for j in range(M):
      I[i][j] = 1 if i == j else 0
      while b:
      if b & 1:
      I = mul(I, a)
      b >>= 1
      a = mul(a, a)
      return I


      n, m = map(int, input().split())

      # Fn = [fn, fn+1, Sn]
      F1 = [1, 1, 1]
      A = [[0, 1, 0], [1, 1, 1], [0, 0, 1]]

      B = quickpow(A, n - 1)
      ans = F1[0] * B[0][2] + F1[1] * B[1][2] + F1[2] * B[2][2]

      print(ans % m)
    • 快速倍增法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      '''
      Author: NEFU AB-IN
      Date: 2022-04-04 17:11:22
      FilePath: \ACM\Acwing\1303.1.py
      LastEditTime: 2022-04-04 17:17:12
      '''


      def dfs(x): #存的是二元组 [f[x], f[x + 1]]
      if x == 0:
      return [0, 1]
      f = dfs(x >> 1) #往下递归
      # k 为 上一层的x
      f1 = (f[0] * (2 * f[1] - f[0])) % m #f1 = f(2 * k)
      f2 = (f[0]**2 + f[1]**2) % m # f2 = f(2 * k + 1)
      if x & 1: # 说明 x = 2 * k + 1, 说明 f[x] = f2, f[x - 1] = f1,所以f[x + 1] = f1 + f2
      return [f2, (f1 + f2) % m]
      return [f1, f2] # 说明 x = 2 * k, 说明 f[x] = f1, f[x + 1] = f2


      n, m = map(int, input().split())
      print( (dfs(n + 2)[0] - 1) % m )

使用搜索:谷歌必应百度