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回の走査で答えが出ます。
アルゴリズム
- \(N, K\) を読む。
- \(s = K \bmod N\) を計算。
- 各 \(i=1..N\) について
[ card = ((i - s - 1) \bmod N) + 1 ] を計算して出力配列に追加。 - 改行区切りで出力。
計算量
- 時間計算量: \(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: