Official

B - 円形カード回し / Circular Card Rotation Editorial by admin

gpt-5.3-codex

概要

カードは毎回「全体で1つ時計回りに回転」するだけなので、\(K\) 回後の状態は \(K \bmod N\) だけずらした結果として一発で求められます。

考察

この操作の本質は、カードが1回の操作で時計回りに1人分進むことです。
つまり、カード番号 \(x\) は初期状態で子供 \(x\) が持っていて、1回後は子供 \(x+1\)、2回後は子供 \(x+2\) …(いずれも \(N\) で循環)となります。

逆に「\(K\) 回後に子供 \(i\) が持つカード」は、 - もともと \(K\) 人ぶん反時計回り側にいた子供のカード です。
これを式にすると、\(s = K \bmod N\) として

[ \text{ans}[i] = ((i - s - 1) \bmod N) + 1 ]

\(i\) は 1-indexed)。


素朴解がなぜだめか

素朴に「1回の操作をそのままシミュレーション」すると、1回あたり \(O(N)\)、合計で \(O(NK)\) です。
しかし \(K \le 10^{18}\) なので、これは到底間に合いません。


どう解決するか

円環上の移動は周期 \(N\) を持つため、\(N\) 回動くと元に戻ります。
したがって必要なのは \(K\) そのものではなく \(K \bmod N\) だけです。
あとは各子供について上の式で直接カード番号を計算すれば、1回の走査で答えが出ます。

アルゴリズム

  1. \(N, K\) を読む。
  2. \(s = K \bmod N\) を計算。
  3. \(i=1..N\) について
    [ card = ((i - s - 1) \bmod N) + 1 ] を計算して出力配列に追加。
  4. 改行区切りで出力。

計算量

  • 時間計算量: \(O(N)\)
  • 空間計算量: \(O(N)\)(出力を配列にためる分。逐次出力なら \(O(1)\) にもできる)

実装のポイント

  • Python の % は負数でも非負に正規化されるため、(i - s - 1) % N で安全に循環インデックスを扱えます。

  • 問題は 1-indexed なので、式の中で -1+1 を入れてずれを調整しています。

  • K が非常に大きいので、必ず最初に K % N を取るのが重要です。

    ソースコード

import sys

def main():
    N, K = map(int, sys.stdin.readline().split())
    s = K % N
    out = []
    for i in range(1, N + 1):
        card = ((i - s - 1) % N) + 1
        out.append(str(card))
    sys.stdout.write("\n".join(out))

if __name__ == "__main__":
    main()

この解説は gpt-5.3-codex によって生成されました。

posted:
last update: