96. 今日解いた問題(2022.04.06)
今日解いた問題についてまとめます。
自分で解きたい方のために、最初に問題だけ置いて、後で自分の解法を書きます。
問題一覧
- A - Bridge and Sheets (Diff: 247)
- B - Reserve or Reverse (Diff: 934)
- C - The Majority (Diff: 1560)
自分の解法など
A - Bridge and Sheets
最適な戦略を考察します。
たとえば、長さ のシートで の部分を覆うことを考えます。全てを覆うことが要求されているため、いずれは左端にシートを置く必要があります。よって、とりあえず左端にシートを置くと の部分が覆われます。次に、同じように考えていずれは の場所にシートを置く必要があります。
このように考察すると、長さ の連続する区間が覆われていないとき、シートは少なくとも 枚必要であり、また、これが最適解です。
よって、既に存在する 枚のシートを座標昇順に並べて、覆われていない区間の長さを算出して各部分に必要な最小シート枚数を算出し、足せば答えになります。ちなみに、この問題では予め は座標昇順に並んでいるため、ソートする必要はないです(ソートしても間に合います)。
計算量は です。
B - Reserve or Reverse
最適な戦略を考察します。
例 1 を見ます。a を 1 文字目に持って行きたいので、 としたいです。これ以上取れないので、結局これが最適解になります。
例 3 を見ます。a をなるべく前方に持って行きたいです。この例を見ると、後ろから順に見て a を貪欲に選択し、前から順に入れ替える戦略が有効そうです。今回はこの考え方がベースになります。
前方に持ってくる文字は a とは限りません(例 4 を見れば分かります)。どのように前方へ持っていく文字を決定するか考えます。
入れ替え操作をイメージすると、「現在入れ替え対象となってる前方の文字」と「現在確認している後方の文字」の間に「後方の文字」より小さいものが無ければ前方に持って行けばよいことが分かります(もし間に小さいものがあれば、それを前方に持ってくる方が辞書順は小さくなります)。ここでさらに考察すると、「前方の文字」が「後方の文字」より小さい場合は入れ替え操作をしない方がよいと分かります。
以上より、次のような操作で辞書順最小の文字列を作ることができると分かりました。
- 前方のインデックスを 、後方のインデックスを として、 で初期化する。 'a'(文字)とする
- または 'z'(文字)なら終了
- となる が存在しないなら として 2. へ
- なら何もせず として 2. へ
- なら を入れ替えて 、として 2. へ
- として 2. へ
ここで問題となるのは 3. の「間に文字が存在するか?」の判定です。ここを定数時間に落とすため、文字ごとに登場回数の累積和配列 (長さ )を取っておきます。 であれば、 から の間にその文字は存在しないです。これによって、事前計算 、判定 が達成できます。
以上より、 で解くことができました。
C - The Majority
状況を上手く整理します。
とりあえず全ての箱に のボールを少なくとも 1 つ入れておく必要があるため、そうしておきます。
その後、各箱において のボールが過半数を維持するように他のボールを入れていくことを考えます。これは、 以外のボールを入れるとき、一緒に のボールを入れてやることで達成できることが分かります。逆に、このような操作ができないと過半数は達成できません。
この操作で 以外の全てのボールを箱に入れて、なお のボールが余っていた場合はどこに入れても良いです。これで全てのボールを箱に入れられました。
操作をまとめると、
- 【0】 または であるなら達成不可能(0 通り)
- 【1】 のボールを、 個の箱に各 1 つずつ入れる
- 【2】 のボールを 1 つずつ、 のボールとペアにして任意の箱に入れる
- 【3】 のボールが余っているなら、1 つずつ任意の箱に入れる
それぞれの操作が何通りあるかを式で表現すると、
- 【1】1
- 【2】
- 【3】
となります。ここで【2】の式について ですが、制約より の方が上限が小さいので とした方が計算量を落とせます。また、Combination の計算で出てくる除算は mod 逆元を利用します。
まとめると、
が答えで、計算量は です。