geam1113’s diary

主にAtcoderのコンテストの備忘録を書きます。AtCoder緑と水色を行ったり来たりしています。

ABC241 参加記録

コンテスト中AC:A〜C,E
コンテスト後、Dは自力AC

2022/07/06追記
Eの実装に単射や同値類という記載がありますが、誤りです。 無視してください。

D - Sequence Query

実装が複雑になりましたが、自作双方向連結リストでACしました。

  • 出現した整数の昇順ソートされた順序集合S (set)
  • 初めて出現した整数が双方向連結リストに何番目に挿入されたかを記録するハッシュマップM (unordered_map)
  • 双方向連結リストD

を準備します。
それぞれにあらかじめ、-\infty , \inftyを入れておきます(番兵)。
Dには昇順に値が挿入されていくように処理します。

具体的には、i番目のクエリは以下のように処理します。

クエリ1 x

  1. xDに初めて挿入される場合、MDの何番目に挿入されたかを記録する。
  2. xより大きい最小の整数ySから二分探索で得る。
  3. yDの何番目に挿入されたかをMから得る。これをj番目とする。
  4. Dにおいて、j番目に挿入された値(y)の後ろにxを挿入する。

クエリ2 x k

  1. xより大きい最小の整数ySから二分探索で得る。
  2. yDの何番目に挿入されたかをMから得る。これをj番目とする。
  3. Dにおいて、j番目に挿入された値(y)から後ろにk回辿る。この時、途中または最後に-\inftyにたどり着いた場合、-1とする。そうでない場合、辿った先を答えとして出力する。

クエリ3 x k

  1. xより大きい最小の整数ySから二分探索で得る。
  2. yDの何番目に挿入されたかをMから得る。これをj番目とする。
  3. Dにおいて、j番目に挿入された値(y)から前にk-1回辿る。この時、途中または最後に\inftyにたどり着いた場合、-1とする。そうでない場合、辿った先を答えとして出力する。

multisetを使うとイテレータの増減だけでいいようです。今更ながら勉強になりました。

提出コード

E - Putting Candies

i\rightarrow (i+A_i)\ mod\ Nに移動すると考えます。
常に移動先は同じなので、鳩の巣原理によって、多くともN回くらい移動すると、同じ場所が2回現れ、その後ループします。

あとは、K回の移動で何回iから移動するかをカウントすれば答えを計算できます。

それを自作ライブラリ化してあったので、よければ参考にしてください。
実装はコンテスト後に少し修正してあります。

なお、この問題は各頂点が有向辺を1つだけもつグラフとも捉えられます。
そのようなグラフは閉路を1つだけ持ち、すべての頂点は閉路に属するか、閉路へ向かうように向きづけられています。
(ここで一応証明してみてあります。AtCoderの過去問の記事なのでネタバレ注意)

提出コード