ABC152 D - Handstand 2
解法
のうち、をある値に決めた際にペアの相手となりうるの個数がいくらか、を高速で求めることができれば、について全探索をして数え上げれば良いです。
の値を決め打ったときに、の末尾の値と先頭の値は固定されてしまいます。
前者はの先頭(これをとします)、後者はの末尾(これをとします)です。
これ以降は、となるような数を、桁ごとに数え上げていきます。
まず、との値が等しいとき、という1桁の数がの候補になります。答えに1加算します。
桁(ただし2以上)ので、の候補になるようなものが何通りあるかを考えます。
まず、桁の場合、少なくとも以上の数字であることが確定します。
そして、のの部分は、桁であり、からまでの通りあることがわかります。
これらのパターンが、以下であるかどうかチェックしつつ加算するには、
を計算してあげればよいです。
ABC149 F - Surrounded Nodes
解法
ある頂点が白であったときに、その頂点がに含まれる確率を計算します。すると、この確率は、どの頂点についても独立に計算できるので、全ての頂点について同じことを計算して足すことで、その総和が答えとなります。
また、確率は、に含まれるパターン数を、で割ったものになるので、に含まれるパターン数を数えていきます。
まず、今計算したい頂点が木全体の根であった場合について考えます。
根に対する子が個存在していたとすると、その個の頂点を根とする部分木について黒い頂点があるかどうかを調べたときに、2つ以上の部分木に黒い頂点が存在していれば、今計算したい頂点がに含まれることになります。
ある部分木について、その部分木に含まれる頂点の個数をとします。すると、
全てが白になるパターンは明らかに1通りなので、少なくとも1つ以上の頂点が黒になるパターンは、通りになります。
ので、個の部分木について、2つ以上の部分木に、1つ以上の黒い頂点が含まれているようなパターンは、全体から、全て白の頂点になるパターンと、1つの部分木のみが黒い頂点を含み、それ以外の部分木は全て白の頂点になるパターンを引けばよいので、
となります。
ある頂点を根とした部分木の全体の頂点数は、適当にDFSをすることによって求めることができるので、上の計算をすることによって、木全体の根が白だった場合に、に含まれるパターン数を計算することができました。
あとは、ある頂点が木全体の根でなかった場合に、その頂点が白かつに含まれるパターン数です。
このときは、を一つの部分木とします。これは、親を辿っていくことができる部分になります。この部分木と、もともとある子の部分木について、上と同様の計算をしてあげればよいです。
1つめの図が、根について見ているパターンです。枠で囲まれているのが、考慮すべき部分木です。
2つめの図が、根の子における頂点を1つピックアップしたパターンです。こちらも、枠で囲まれているのが、考慮すべき部分木です。
2つめの図において、茶色の部分木の頂点数を調べるには、青、水、緑の部分木の頂点数の総和+今見ている頂点自身を、から引いてあげればよいです。
青、水、緑の部分木の頂点数は、1つめの図で頂点数を数える時点で計算済みのはずなので、これで簡単に計算することができます。もしくは、から、赤い枠の頂点数をひけばよいです。
全ての頂点数について、を計算したら、これをで割ったものが答えになります。
ABC149 E - Handshake
解法
明らかに、得点の和が高いペアから順番に握手をしていくのが最適です。
ある得点が達成できるとすると、明らかに未満の任意の得点は、全く同じ手を選ぶことで達成でき、達成できないときは以上の得点はどう頑張っても達成できないので、
- 以上の得点を達成できるか
について単調性が存在します。
このについて二分探索をしたいのですが、うまくいきません(僕はいきませんでした)。ので、少し見方を変えます。
得点の和が高いペアから順番に握手をしていくのが最適だったので、ある得点について、
- 以上となるペアについては握手を行い、未満となるペアについては握手をしない
という区切り目が存在するはずです。
以上となるペアの個数が個以上になると、回握手することができます。
以上となるペアの個数についても、が減少すれば個数が増加し、単調性が存在しています。ので、
- 以上となるペアの個数が以上になる
ような、最大のを二分探索で求めることができます。
すると、その以上のペアの総和を求めればよいです。
片手がのとき、もう片方の手は、以上のを選ぶことができます。このの個数は、が降順ソートされていれば、二分探索で求めることができます。
これにより、ペアの個数を求めることができました。
総和についてもほぼ同様で、からまでの総和と、の総和を全てのについて足したものになります。
これは、後者についてはそのまま個数をかければよく、前者については累積和をあらかじめ計算しておくことで、高速に計算することができます。
あとは、コーナーケースである、
- 以上となるペアの個数がぴったりではなかった場合
についての差分を計算すればよいです(サンプル2参照)。
得点の和が以上となるペアは個未満になってしまうはずなので、今以上となるペアの個数が個あるとしたときに、総和から除くべき個のペアは、得点がとなっているものについてです。
ということで、を、全体の総和から引いてあげれば求める答えとなります。
感想
見るからに二分探索をしたいなぁ、と思っていたのですが、うまく二分探索をする方法を考えるのに詰まってしまいました。
見方の変え方が課題です。
ARC050 B - 花束
解法
個の花束を作成できるかどうか、を調べます。
まず、2種類の花束どちらも、1つの花束につき少なくとも1本使用することになるので、最低本ずつ使用することになります。
この部分を除くと、
赤い花を本使用する
青い花を本使用する
の2通りの操作どちらかを行うことで、1つの花束を作成することができます。
ので、結局、
であれば、個の花束を作成することができます。
この条件を調べて、個の花束を作成することができるとわかったとき、個未満の花束は明らかに作成することができます。
ということで、単調性が存在するため、上の条件を満たす最大のを二分探索で求めれば答えとなります。
感想
個数を決め打ち、どちらか片方のコストを0にして考えやすくする、といったよくある考え方が詰まっている気がします。
ARC044 B - 最短路問題
解法
頂点1が距離0でない場合や、頂点1以外が距離0である場合は、明らかに答えが0になるので処理しておきます。
それ以外のグラフについて考えます。
あらかじめ、距離がの頂点の個数をそれぞれカウントしておきます。
距離がである頂点は、距離がである頂点、である頂点、である頂点に向けて辺を張ることができます。である頂点との辺は、距離がである頂点から張る辺について考慮するときに計算すればよいので、距離がである頂点について考えるとき、の頂点との頂点に向けて張る辺についてのみ計算していきます。
距離の頂点に向けての辺の張り方
距離の頂点を1つ選びます。すると、この頂点は、距離がである頂点のうちすくなくとも1つの頂点に向けて辺が張られていなければなりません。
今選んだ頂点と、個の頂点との辺の張り方は、通りありますが、この中で選んではいけないパターンは、どこにも辺が張られていないパターンただ1つです。
ということで、距離の頂点1つに対し、距離の頂点との辺の張り方は通りとなります。
これが、個の頂点について同じことが考えられるので、最終的に距離の頂点との頂点についての辺の張り方は、
通り
です。距離の頂点同士を結ぶ辺の張り方
距離の頂点同士を結ぶ辺の張り方は、通りです。今回は、全ての辺について、張る、張らないの2パターンを自由に選べます。
ということで、
通りの張り方が存在します。
ということで、の最大値をとして、
が答えとなります。