AtCoder Beginner Contest 282 備忘録
コンテストページ: HHKB Programming Contest 2022 Winter(AtCoder Beginner Contest 282) - AtCoder
コンテスト後にAC: A〜C
コンテスト後にD,Eは自力で解けず 。Fは自力AC
D - Make Bipartite 2
コンテスト中はよくわからない勘違いでACできませんでした。
まず、連結成分に2部グラフでないものが含まれていた場合、辺追加後のグラフも2部グラフにならないので0です(これが抜けていました)。以下、全ての連結成分が2部グラフであるとします。
まず、連結成分内同士を繋ぐ場合の辺の本数を求めます。
連結成分の1つについて、頂点を2つの独立集合とに分けます。これは頂点を2色彩色した場合に同色となる頂点集合と同じです。
または内で辺を繋ぐと2部グラフでなくなります。との頂点同士はどのように繋いでも2部グラフのままです。
の任意の頂点について、の全ての頂点と辺を繋ぐことが可能なので、合計本の辺を繋ぐことができるわけですが、既に辺が存在する場合はその分を引かなければなりません。
つまり、は本の辺を繋ぐことができます。但し、はから出ている辺の本数とします。
従って、連結成分内で繋げる辺の本数はについて、で繋げる辺の本数の総和を求めればよいです。
次に、連結成分間です。
任意の連結成分間では、全ての頂点間の辺を繋ぐことができます。もし、頂点を2色彩色した場合の同色同士を辺で繋いだとしても、一方の連結成分の色を全て反転させればよいです。
よって、連結成分の頂点数の合計がであり、の頂点数がだとすれば、本の辺を繋ぐことができます。
以上から、連結成分間について、連結成分の頂点数の和を順次計算しながら、辺の本数を求めていくことができます。
実装: Submission #37366599 - HHKB Programming Contest 2022 Winter(AtCoder Beginner Contest 282)
E - Choose Two and Eat One
公式解説を見ました。
こういう問題はどうやったら気づけるのか難しいところです。
AtCoderの過去問 (ネタバレ注意)で、似たような感じの木で考える問題もありました。これも葉から順に操作していくというものでした。
1つずつ選んでいく感じの問題は木を疑ってみると良いのかもしれません。
F - Union of Two Sets
公式解説そのままだったので、解法の詳細は省略し、解法に至った経緯だけメモしておきます。
まず、全ての区間の組を得ようとした場合、個必要です。ワーストケースのの場合だけを考えても、という制約を越えるため、全ての区間を列挙することは不可能です。
そこで、例えば、区間の数を個に落とすことができれば、解決できそうです。
そんなわけで、区間の長さを2分の1ずつ小さくすることを考えます。
N=10を例にします。10/2=5なので、長さが5の区間について考えます。 全ての長さ5の区間をカバーするためには、始点を1つずつずらす必要があります。そのため、
[1,5] [2,6] [3,7] [4,8] [5,9] [6,10]
が必要です。
これを眺めたところ、ここから適切に区間を2つ選ぶことで長さ5〜10の区間すべてをカバーできることがわかりました。
一般化すると、
また、各長さの区間の個数は個以下となることから、全ての区間を列挙しても個以下となります。
以上から、のすべての区間を列挙しておけば、クエリに答えられます。
クエリでは、区間の長さ以下となる最大の2の冪乗について、その指数が必要になります。
これは、ビットが1である最上位のビットが何番目かを得ればよいです(__builtin_clzが使えます)。
実装: Submission #37417443 - HHKB Programming Contest 2022 Winter(AtCoder Beginner Contest 282)