2020年10月30日金曜日
2020年10月23日金曜日
ARC 093 E - Bichrome Spanning Tree
XがMSTの重みの総和より小さい場合は実現不可能である。
XがMSTの重みの総和に等しい場合、MSTを作れるような塗り方を数えればよい……が、そもそも、だいたいの塗り方においてMSTが作れるように見える。というのも、MSTに使える辺が全部白または全部黒になっているような塗り方を除けばMSTができるからだ。つまり、MSTに使われうる辺がK本あるとき、K本全部を一色で塗る2⋅2M−K通りの塗り方以外はMSTを作れる。あとはKが求まればよい。これは最小全域木Tを作った後、M本の辺e=(u,v)について最適性条件を満たせるか判定すれば数えられる。具体的には、eの重みが(T上の)パスu−v上の重みのmax以下であればeはMSTに使える[1]。変更がないので、maxクエリはダブリング等で処理できる。(制約をN=105と勘違いしていた。愚直でよい。)
XがMSTの重みの総和より大きい場合、MSTに使われうる辺は全部白または全部黒に塗られていなければならないので、とりあえず白に塗られているとする。この時、黒に塗られていてMSTに使えない辺が全域木に少なくとも1本含まれていなければならないが、その1本以外は白い辺も自由に選べる。したがって、MSTに対して辺を挿入してそれによってできたサイクルから別の最大辺を削除して全域木を作った時に、重みの総和がXになるものを考えればよい。これにはやはり木上のmaxクエリで答えられる。「MSTの辺と交換した時の重みの総和」がXになる辺をp本、Xより大きくなる辺をq本としたとき、p本から少なくとも一つを黒い辺にする必要があって、q本は好きにぬってよいので、塗り方は(2p−1)2q通り。白の分と黒の分を足すと2⋅(2p−1)2q通りとなる。O((M+N)logN)。
厳密な証明がよくわからなかった。
path optimality condition ↩︎
2020年10月17日土曜日
ABC 180 F - Unbranched
「最大サイズがちょうどL」の代わりに、f(n,m,l):=連結成分のサイズがlを超えないn頂点m辺のグラフの数、を数えることにして、f(N,M,L)−f(N,M,L−1)を答えとすればよい。
次数2以下の連結成分はパスかサイクルしかないので、この2つを作りながら数えていくDPができそうだが、頂点の順番をどうするかが問題になる。順番を固定した上で最後に定数を掛けるのはうまくいかなそうだし、固定せずに挿入していくDPもサイズの上限に関する制約を扱うのが困難に見える。
こういう時の典型テクニックの一つとして、「選ぶ頂点の一つは、残っているものの中でもっとも小さい番号とする」というルールを追加してグループ(この場合は連結成分)を作っていくというものがある。この場合はこれがうまくいきそうだ。
dp[x][y]:=頂点をx個、辺をy個使ってできる(条件を満たす)グラフの総数
とする。残ったN−x個の頂点からサイズsのパスグラフを作る時、連結成分のうちの1つの頂点は残った頂点の中でもっとも番号の小さいものと決めているので、残りはN−x−1個からs−1個を選ぶことになる。ラベル付きパスグラフの総数はs!/2(ただしs=1の場合は例外)なので、
dp[x+s][x+s−1]+=2s!(s−1N−x−1)dp[x][y]と遷移できる。サイクルを作る場合も同様で、ラベル付きサイクルグラフの総数は(s−1)!/2(ただしs≤2の場合は例外)なので、
dp[x+s][x+s−1]+=2(s−1)!(s−1N−x−1)dp[x][y]と遷移する。ただし、自己ループであるs=1は許されないことに注意。
2020年10月12日月曜日
CodeChef October Challenge 2020 - Compress all Subsegments
区間Iに関するfの値は、(Ai)i∈I中のhighest set bitの位置をkとして、kが立っている数が(Ai)i∈Iに何個含まれるかでだいたい決まる:
- kが立っている数が1個でそれ以外が0個の場合、その数自身になる
- kが立っている数が奇数個の場合、上の場合を除いて2kになる
- kが立っている数が2個でそれ以外が0個の場合、不定
- kが立っている数が2個でそれ以外が1個の場合、不定
- kが立っている数が2個でそれ以外が2個以上の場合、0にできる
- kが立っている数が4個でそれ以外が0個の場合、不定
- kが立っている数が4個でそれ以外が1個以上の場合、0にできる
- kが立っている数が6個以上の偶数の場合、それ以外が何個でも0にできる
まずは、kが立っている数が偶数個の時に常はfの値が0になり、kが立っている数が奇数個の時は常に2kになるとして、偶奇のみに注目して計算する。そして、後から3, 4, 6のパターンを別に数えて補正する。
前半パートは、i=1,2,...,Nについてそれぞれ区間[1,i],[2,i],...,[i,i]に関する結果の和を求めるとよい。この際、
- odd[x]:= highest set bitがxで、xが立っている数を奇数個含むような区間の数
- even[x]:= highest set bitがxで、xが立っている数を偶数個含むような区間の数
を保持しながら走査するとまとめて計算できる。O(NlogmaxAi)。