AtCoder Beginner Contest 221のきろく
久しぶりの更新です。AtCoder Beginner Contest 221に参加です。
- A - Seismic magnitude scales (100点)
- B - typo (200点)
- C - Select Mul (300点)
- D - Online games (400点)
- E - LEQ (500点)
- F - Diameter set (500点)
- G - Jumping sequence (600点、実行時間制限: 5 sec): 未提出
- H - Count Multiset (600点): 未提出
- 結果、感想
A - Seismic magnitude scales (100点)
答えは となります。pow
などを用いてもこの問題ではOKですが、場合によっては誤差が発生しうるのでfor
文を使うのが無難と思いそちらで組みました。
B - typo (200点)
問題文の通り、何も操作を行わないとき、 文字目と 文字目を入れ替えたとき、それぞれについて一致するかどうかを調べることで解けます。
実装的には各 について 文字目と 文字目を入れ替えたときと戻した時を判定すれば、何も操作を行わないときについて別個に書く必要がなくなるので、コードは短くなりますね。
C - Select Mul (300点)
の各桁の数字を任意の順番に並べて、その先頭の数と、後ろの数と見做すことで全ての分離方法を考えることができ、その方法は の桁数を とするとき 通りあり、計算量も となります。
ここで、各分離方法について、それぞれの数字を降順にソートした方が答えが大きくなるため、各数字を2つのグループのどちらかに所属するかの 通りのみの分離方法のみ調べる必要性があることになります。これはbit全探索を用いて計算量 で実装できます。
本番では後者の方法がすぐ思い浮かんだので、そちらでのみ実装しました。
どうやら 解 や 解があるようですが、こんなの本番中に思いつけへんやん...
D - Online games (400点)
全ての日について考えると最大で 日目まで考える必要があるので、間に合いません。人数の変動があるのは各 について 日目と 日目なので、その節目で人数が何人になって、その間隔が何日なのかを計算することで答えを求めることができます。
本番では間隔の前後を間違えて1WAしました。
E - LEQ (500点)
が , が であるような部分列の個数は のそれぞれを選ぶかどうかの 通りであるため、求める答えは です。
であるため として を選んだ時、 となるような について を足していき、 で割ることでこのときの部分列数が求まります。よってこれを全ての について足していけばいいことができます。
これは について という重みを付けた個数のセグ木について添え字の降順に走査することで実装することができますが、 の値が 程度になることにもなるため座標圧縮してやる必要があります。
本番ではセグ木の演算でmodをとらせるということをしていなかったため1WA出してしまいました。
F - Diameter set (500点)
木の直径はdouble sweep によって求めることができます。そこから木の中心 を求めますが、この時、直径の偶奇で場合分けをしますが、各辺上に頂点を追加してやることで、直径を2倍にし、偶数にすることができ、この直径を とします。
この木を を根とする根附き木として、 の直接の子を として、 以外の点をそれぞれどの の子孫(または 自身)であるかでグループ分けします。各グループについて からの距離が であるような点の個数を とします。条件を満たす点の選び方は各グループについて距離 の点を高々1つづつ選んでいき、かつ選んだ個数が 以上のものであるため、 通りとなります。
本番ではグループを高々2つまでしか考えてなくて爆死しました。
G - Jumping sequence (600点、実行時間制限: 5 sec): 未提出
何かしら圧縮してDPなんやろうなぁと思ってます。
H - Count Multiset (600点): 未提出
DPなのかな
結果、感想
8問ABCになってから調子悪かったのですが、久しぶりに良いパフォが取れました。このまま1700まで恢復していきたいですね。