12/14 ABC384-D(14日目)

13日目の記事に戻る

こんにちは、ゆーてぃーです。今回は「ゆーてぃーのAtCoder精進【14日目】」ということで、2024年12月14日に行われたABC384のD問題を解きたいと思います。

ゆーてぃーのAtCoder精進 Advent Calendar 2025

問題

D - Repeated Sequence

問題ページ

問題文

周期 Nをもつ無限数列 A=(A_1​,A_2​,A_3​,…)の先頭 N A_1​,A_2​,…,A_N​ が与えられます。

この数列の空でない連続する部分列のうち、和が Sとなるものが存在するか判定してください。

ただし、無限数列 Aが周期 Nをもつとは、 i > Nを満たすすべての整数 iに対して A_i​=A_{i−N} が成り立つことをいいます。

制約

  •  1 \leqq N \leqq 2 \times 10 ^ 5
  •  1 \leqq A_i \leqq 10 ^ 9
  •  1 \leqq S \leqq 10 ^ {18}
  • 入力はすべて整数

入力

入力は以下の形式で標準入力から与えられる。

 N\ S

 A_1\ A_2\ ...\ A_N

出力

 Aの連続する部分列 (A_l​,A_{l+1}​,…,A_r​)であって、 A_l​+A_{l+1}​+⋯+A_r​=Sとなるものが存在するならば Yes を、そうでないならば No を出力せよ。

ゆーてぃーの解法

先頭 N項のまとまりで考えると、 S=先頭 N項の総和 \times n +先頭 N項の一部の総和となることがわかります。そしてその一部は必ず先頭 N項のうち連続している部分の和となるので、 S \%先頭 N項の総和 の値が連続している部分の和かどうか判断すれば求められます。先頭 N項の累積和をとることで先頭 N項の部分和を計算することができます。ただし、数列 1\ 2\ 3\ 4\ 1\ 2\ 3\ 4\ 1\ 2\ 3\ 4のうちの 4\ 1\ 2\ 3\ 4\ 1\ 2の部分が答えになっているとまとまり以外の連続している部分は 4\ 1\ 2となります。これは先頭 4項の一番右の 4から連続した3つを取らないといけません。なので先頭 N項を2つ並べて累積和とることで実現できます。右(2つ目の先頭 N項)にずれていくごとに探索範囲外となった A_iを引いていけば先頭 N項の N-1から 2番目の総和も求められます。

あとはこの累積和に対して二分探索を行い、 S \%先頭 N項の総和 があればYes、なければNoを出力すればおっけーです。 S \leqq 10 ^ {18}と制約が大きいのでunsigned long longを使いました。

感想など

累積和、二分探索など今まで学んだ内容の総復習のような問題でした。何回も修正を加えて最終的にはACできたのでとても楽しかったです。

提出コード

15日目の記事へ進む