外部サイトへ移動します

リンク先の URL を確認してから開いてください。

別タブで開く

解説

C - Add to Multiples

作成者 loop0919

テスター mackerel38

配点 300 点

実行時間制限
2 秒
メモリ制限
512 MiB

解説

i<i′i < i' のとき、 k=i′k = i' の操作は k=ik = i の操作に影響を及ぼさないことに着目します。
この考察により、 ii の昇順に AiA_i の値を XiX_i の値に貪欲に揃えるのが正当であることが分かります。

よって、以下のアルゴリズムが正当です。

  • k=1,2,⋯ ,Nk = 1, 2, \cdots, N の順に以下の処理を行う。
    • Ak,A2k,⋯ ,A⌊N/k⌋kA_k, A_{2k}, \cdots, A_{\lfloor N/k \rfloor k} に対し、 x=Xk−Akx = X_k - A_k を加算する。

また、この加算回数は調和級数の和を考えることで O(Nlog⁡N)O(N \log N) 回に抑えられます。

計算量はテストケースごとに O(Nlog⁡N)O(N \log N) であり、これは本問題の制約下において十分高速です。
言語と実装方針によってはオーバーフローが発生する場合があるため、十分注意してください。

実装例 (Python3)

def solve():
    N = int(input())
    X = [int(s) for s in input().split()]

    A = [0] * N
    answers = []

    for i in range(1, N + 1):
        diff = X[i - 1] - A[i - 1]
        answers.append((i, diff))
        for j in range(i - 1, N, i):
            A[j] += diff

    print(len(answers))
    for k, x in answers:
        print(k, x)

T = int(input())
for _ in range(T):
    solve()

ユーザー解説

ユーザー解説を書く

ユーザー解説はまだありません。