結果
問題 | No.194 フィボナッチ数列の理解(1) |
ユーザー |
![]() |
提出日時 | 2025-03-20 20:44:58 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 89 ms / 5,000 ms |
コード長 | 2,798 bytes |
コンパイル時間 | 217 ms |
コンパイル使用メモリ | 82,384 KB |
実行使用メモリ | 81,684 KB |
最終ジャッジ日時 | 2025-03-20 20:45:06 |
合計ジャッジ時間 | 3,880 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 37 |
ソースコード
import sys from collections import deque MOD = 10**9 + 7 def build_transition_matrix(n): size = n + 1 T = [[0] * size for _ in range(size)] # Row 0: sum of first N elements for j in range(n): T[0][j] = 1 # Rows 1 to n-1: shifted for i in range(1, n): T[i][i-1] = 1 # Row n: sum of first N and 1 in column n for j in range(n): T[n][j] = 1 T[n][n] = 1 return T def matrix_mult(a, b, mod): n = len(a) m = len(b[0]) p = len(b) result = [[0] * m for _ in range(n)] for i in range(n): for k in range(p): if a[i][k] == 0: continue for j in range(m): result[i][j] = (result[i][j] + a[i][k] * b[k][j]) % mod return result def matrix_pow(mat, power, mod): n = len(mat) result = [[0] * n for _ in range(n)] for i in range(n): result[i][i] = 1 # Identity matrix while power > 0: if power % 2 == 1: result = matrix_mult(result, mat, mod) mat = matrix_mult(mat, mat, mod) power //= 2 return result def matrix_vector_mult(mat, vec, mod): size = len(vec) result = [0] * size for i in range(size): for j in range(size): result[i] = (result[i] + mat[i][j] * vec[j]) % mod return result def main(): input = sys.stdin.read().split() ptr = 0 N = int(input[ptr]) ptr += 1 K = int(input[ptr]) ptr += 1 A = list(map(int, input[ptr:ptr+N])) ptr += N if K <= N: F = A[K-1] % MOD S = sum(A[:K]) % MOD else: sum_initial = sum(A) % MOD if N <= 30: # Matrix exponentiation approach reversed_A = list(reversed(A)) initial = [a % MOD for a in reversed_A] initial.append(sum_initial % MOD) T = build_transition_matrix(N) power = K - N T_power = matrix_pow(T, power, MOD) result_state = matrix_vector_mult(T_power, initial, MOD) F = result_state[0] % MOD S = result_state[-1] % MOD else: # Deque approach deque_list = deque() for a in A: deque_list.append(a % MOD) deque_list.append(sum_initial % MOD) steps_needed = K - (N + 1) S = (sum_initial * 2) % MOD for _ in range(steps_needed): current_last = deque_list[-1] first = deque_list.popleft() new_F = (2 * current_last - first) % MOD new_F = (new_F + MOD) % MOD # Ensure non-negative S = (S + new_F) % MOD deque_list.append(new_F) F = deque_list[-1] % MOD print(F, S) if __name__ == "__main__": main()