ARC178

3完。本当に久しぶりの"勝ち"に感じる。これで冷えてたら「Aはクソ」とか言うのかもしれないが、気分がいいので全然そんな感情は出てこない。Dが、解けないまでも30分しっかり考えられたのが満足感高い。

A - Good Permutation 2

問題文を今読み返しても全然わからない。Aの順番関係ないなら列じゃなく集合で与えてくれ。不安になる。

まず、Aに1かNが含まれていたら自明に-1。次に、1からNまで置いていく。先頭は1。2がAに含まれていたら2は置けないので3にする。置けなかった2をストックしておく。3がAに含まれていたらその2を置けないので4を置く。そうでないとき2を置ける(Aに4や5が含まれていてもあとから調整できる)。ストックは常に1個以下で、ストックがあるときは1大きい数を置く。ストックの有無とAに含まれるかで4通り書く。なんとなくでAC。

B - 1 + 6 = 7

A_1 >= A_2 としてよい(必要ならswapする)。自分と同じか小さい桁数のやつを足したら、桁数は変わらないか1増えるかのどちらか。その2通りを考えるのかというと、X_1とX_2の、和の桁数を無視した通り数は簡単に求まるので、桁数が増える通り数だけを求めればいい。最上位の桁は0でないというのが嫌らしい。まず同じ桁数のもの同士を足す場合を考える。3桁で考えると、どちらも100以上。基本的に、3桁の正整数Xの(足して桁数が増える3桁の)相手はX通り。ただし、相手も100以上である必要があるので、900以上はずっと900通り。桁数が違う場合は、桁数大きい側が0以上100未満のときもいけるのでその分を足す(0のときは0通りだがきりがいいので)(ここの処理を削除してもサンプルは通るので不安だったが提出した)。なかなかサンプルが合わず、例で考えていた100をそのまま一部に埋め込んでしまっていた。

C - Sum of Abs 2

ΣΣのところは、要するに全部のペアの和だから、Bはソートされているとしてよい。B全体に同じ数を足してもこの和は変わらないので、Bの最小値は0としてよい。Bが与えられたときいい感じに計算する方法(この問題で使えるような)を見つけたい。しばらく考えて、最初数直線の0の位置にあるL個の点を、L-1個移動させ、L-2個移動させと繰り返すことで、ソートされたBの隣接要素の差と (L-1)*1, (L-2)*2, ... , 1*(L-1) の積の和で計算できるとわかった。差は0でもいい。ダブりがあるけどそれは重複削除していい。同じものを何回使ってもいい(合計10回使ったら対応する差を10にすればいい)。この辺りけっこう難しくて、実装しながら理解していった。

ここまでやってもまだ奥があるのか、と思ったけど、しばらく考えるとこれはナップサックみがある。ひええそんな構造が隠れていたのか。さっきの(L-1)*1とかはL-1個あるけど2*10^5以下に限れば少ないのではと思い実験すると、目視で500個未満になりそうだとわかった。これなら全体で10^8程度の計算量になり間に合う。その数を作れるmax(B)の最小値でDP。貰うDPで、作る数の小さい順に最小値を求めていく。何を求めたいかが決まれば、DP自体はすぐ書ける。慣れたもんだ。

D - Delete Range Mex

逆から考えてみると、最後に削除された数をmexとする区間がAにあることがわかり、削除する数のうち最小値でないものを最後に削除することはできないので、Aにない数のうち最小のものは最後に削除されたとわかる。Aにない数を小さい順に挿入してくということか。例えば2を挿入するなら、0と1が両方含まれる最短区間の内側はダメ。次に5を挿入するなら、5から見て0と1が両方含まれる最短区間の側に2を挿入する必要がある。これでなんとなく解けそうだと思ったが、最小値が0の場合がある。次だけでなく2つ先までは考える必要がありそう。そもそも挿入したら長さが変わるし。(自分が解けるという意味ではなく)解ける問題には見えるが、実装できる気は全くしない。