geam1113’s diary

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

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つCについて、頂点を2つの独立集合U=\{u_1,\cdots ,u_k\}V=\{v_1,\cdots ,v_m\}に分けます。これは頂点を2色彩色した場合に同色となる頂点集合と同じです。

UまたはV内で辺を繋ぐと2部グラフでなくなります。UVの頂点同士はどのように繋いでも2部グラフのままです。

Uの任意の頂点uについて、Vの全ての頂点と辺を繋ぐことが可能なので、合計m本の辺を繋ぐことができるわけですが、既に辺が存在する場合はその分を引かなければなりません。

つまり、um-N(u)本の辺を繋ぐことができます。但し、N(u)uから出ている辺の本数とします。
従って、連結成分内で繋げる辺の本数はi=1,\cdots ,kについて、u_iで繋げる辺の本数の総和を求めればよいです。

次に、連結成分間です。
任意の連結成分C_i,C_j間では、全ての頂点間の辺を繋ぐことができます。もし、頂点を2色彩色した場合の同色同士を辺で繋いだとしても、一方の連結成分の色を全て反転させればよいです。

よって、連結成分C_1,\cdots C_{i-1}の頂点数の合計がSであり、C_iの頂点数が|C_i|だとすれば、S\times |C_i|本の辺を繋ぐことができます。
以上から、連結成分間について、連結成分の頂点数の和を順次計算しながら、辺の本数を求めていくことができます。

実装: Submission #37366599 - HHKB Programming Contest 2022 Winter(AtCoder Beginner Contest 282)

E - Choose Two and Eat One

公式解説を見ました。
こういう問題はどうやったら気づけるのか難しいところです。 AtCoderの過去問 (ネタバレ注意)で、似たような感じの木で考える問題もありました。これも葉から順に操作していくというものでした。
1つずつ選んでいく感じの問題は木を疑ってみると良いのかもしれません。

F - Union of Two Sets

公式解説そのままだったので、解法の詳細は省略し、解法に至った経緯だけメモしておきます。

まず、全ての区間の組を得ようとした場合、N^2個必要です。ワーストケースのN=400の場合だけを考えても、M\leq 50000という制約を越えるため、全ての区間を列挙することは不可能です。

そこで、例えば、区間の数をNlogN個に落とすことができれば、解決できそうです。
そんなわけで、区間の長さを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の区間すべてをカバーできることがわかりました。
一般化すると、

長さiの閉区間について、[1,i],\ [2,i+1],\ \cdots , \ [N-i+1,N]から適切な2組を選ぶことで、長さ1,2, \cdots ,2iの全ての区間を作ることができる。

また、各長さの区間の個数はN個以下となることから、全ての区間を列挙してもNlogN個以下となります。
以上から、1\leq 2^i \lt Nのすべての区間を列挙しておけば、クエリに答えられます。

クエリでは、区間の長さ以下となる最大の2の冪乗について、その指数が必要になります。
これは、ビットが1である最上位のビットが何番目かを得ればよいです(__builtin_clzが使えます)。

実装: Submission #37417443 - HHKB Programming Contest 2022 Winter(AtCoder Beginner Contest 282)