1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ABC 401 C - K-bonacci

Posted at

ABC 401 C - K-bonacci

↑問題の詳細は上記のリンクを参照ください!
※興味持った方は毎週土曜日21:00からのABCコンテストにratedで参加してみてください⭐️

問題文

正整数 N, K が与えられます。長さ N+1 の数列 A = (A₀, A₁, ..., Aₙ) の各要素の値を、以下の方法で定義します。

  • 0 ≦ i < K のとき、Aᵢ = 1
  • K ≦ i のとき、Aᵢ = A_{i-K} + A_{i-K+1} + ... + A_{i-1}

A_N を 10の9乗(10⁹)で割ったあまりを求めてください。

制約

  • 1 ≦ N, K ≦ 10⁶
  • 入力される数値はすべて整数

解法ポイント

image.png

こんな感じに整理するとK個分の数列Aを配列で管理してあげると解けそうです。

NG例1

from collections import deque

MOD = 10**9
N,K = map(int, input().split())

nums = [1 for _ in range(K)]
dq = deque()
dq.extend(nums)

for _ in range(N-K+1):
  dq.append(sum(dq) % MOD) # O(N*N)になっちゃう。❌制約がN<=10**6なのでMAX 10**12
  dq.popleft()

print(dq[-1])

体感python(pypy)だと10**10超えるとタイムアウトでTLE(誤答)になる感覚です

NG例2

NG例1からO(N*N)からO(N)にどうやってできるか試行錯誤すると
実は、以下のことに気づくとO(N)で計算可能なことに気づきます。

i(>=K+1)の場合は、A[i] = A[i-1]*2 - A[i-K-1]

from collections import deque

MOD = 10**9
N,K = map(int, input().split())

nums = [1 for _ in range(K)]
dq = deque()
dq.extend(nums)

total = sum(dq)

for _ in range(N-K+1):
  dq.append(total % MOD)
  total = (total *2 - dq.popleft()) #ここにMODを置かないと桁がデカくなりすぎてTimeOutする

print(dq[-1])

ACサンプル(正解)

ということで、totalの再計算にもMODを入れるとAC(合格)します。

from collections import deque

MOD = 10**9
N,K = map(int, input().split())

nums = [1 for _ in range(K)]
dq = deque()
dq.extend(nums)

total = sum(dq)

for _ in range(N-K+1):
  dq.append(total % MOD)
  total = (total *2 - dq.popleft()) % MOD

print(dq[-1])
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?