AtCoder ARC 037
February 29, 2020
ARC037の自分用メモ
AtCoder 版!蟻本 (初級編)にC問題が類題として載っていたので解いた。
B-バウムテスト
無向グラフが与えられたとき、その部分グラフで木になっているものの数を答える問題。つまり連結成分で閉路を含まないものの個数を計算する。
連結成分の個数
頂点が訪問済みかどうかを表すリストを用意する。深さ優先探索を適当な頂点を始点として1度おこなうと、その頂点を含む連結成分に含まれるすべての頂点が訪問済みとなる。したがって、連結成分の個数を求めるには、すべての頂点について、それが訪問済みでなければ深さ優先探索をおこなう、という方法で深さ優先探索をおこなった回数を求めればいい。
閉路の検出
閉路が存在すれば、深さ優先探索をおこなっているとき、訪問済みの頂点を未使用の辺で辿ることができる。したがって、頂点が訪問済みかどうかを表すリストと、使用済みの辺のリストを用意して、深さ優先探索をおこない、それらを適宜更新することで、閉路を検出できる。実装では、辺が使用済みかどうかを隣接行列で表せばでその辺が使用済みかどうか調べられる。
実装
C-億マス計算
個の値があって、K番目の数を求める問題。
という条件があるので、個の値をそれぞれ計算して、K番目の数を答えるという方法では当然時間が足りない。適当な数に対して、以下の数が何個あるのか効率的に数えられれば、二分探索でK番目の数を求められる。探索区間は
積()の個数を数える
しゃくとり法で数える。一応、二分探索(lower_bound)を使っても今回は間に合うはず。
例えば、 、が与えられたとき、以下の積の個数を数えたいとする。は以下のようになる。
A\B | 6 | 5 | 4 | 3 |
---|---|---|---|---|
2 | 12 | 10 | 8 | 6 |
3 | 18 | 15 | 12 | 9 |
4 | 24 | 20 | 16 | 12 |
5 | 30 | 25 | 20 | 15 |
緑色で表示された積が以下となっている。上の表で黒色と緑色の境界が、が大きくなるごとに、広義単調増加することに着目して以下の積の個数を効率的に数えるのがしゃくとり法。しゃくとり法の詳細については、このあたり(しゃくとり法 (尺取り法) の解説と、それを用いる問題のまとめ)が詳しい。しゃくとり法を用いると、以下の積の個数をで数えられる。
実装
Aを昇順、Bを降順にソートしているが、別にBを昇順にソートしても同様の方法で解けるしそのあたりは好み。
類題
-
ABC155 D問題 https://atcoder.jp/contests/abc155/tasks/abc155_d
- 負の整数も含むので、この問題より少し面倒だけど、場合分けして数えれば、この問題とほとんど同じように解ける