ARC123

ABのスピードはこんなもん。Aはちゃんと考えて、Bは妥協して雑証明で済ます。CとDでDが難しそうな雰囲気なのでC寄りで交互に考える。C適当に書いて出すがダメ、Dはとりあえずダメそうなの提出して様子見てしばらく考えて時間切れ。

ABは普通だし、CDは悔しさすら感じないくらい何もわからなかった。もちろん嫌な気持ちにはなっている。なんでこんなにパフォ低いんだ?最近調子悪かったしなあ。頭の緩め方がわからない。

A - Arithmetic Sequence

正面からではきつそうなのでバラして操作の寄与を見るかと思っていると、問題文に等差数列の条件が書いてあってそれがそのまま使えた。この2数を等しくしたい。できる操作は3種類で、実質2種類。初期状態でどちらが大きいかで場合分けして、片方がやや面倒で差が5だったら3回2足して1引く感じに。それ以外に等しくする方法がないので解けている。

B - Increasing Triples

貪欲っぽい。全部ソートして小さいものから。一番小さいAから使うのはよさそう(どうせ小さいのは使う)。Cも小さいの使いたいよね(大きいの残したほうが得)。Bが怪しいが、大きいBを使ったほうがいいとして、それによるメリットは小さいBが残ることのみだからそれを誰かが使っているはずだが、それと入れ替えることができるので大きいBを使うメリットなさそう。これ以上は時間がかかりすぎるので、順位表見てから提出した。

ソートし忘れでサンプルが合わず少し時間食った。

C - 1, 2, 3 - Decomposition

かなり捉えどころがなく「ほんとに解けるのか?」という感じ。桁DPっぽく下からやりたいけど、めっちゃ上から繰り下げてくるの大変そうだし、上に行ったとき整合性が崩れて無理そう。DPしようにも、下の桁が何回でできるかは上の桁からの繰り下がりの量に依るので状態が爆発する。だいぶ経って、わからんけど上から考えてそれっぽいやつで実装した。必要条件として、上の桁ほど(1,2,3を引く)回数が少なくないといけない。(下限と上限を比較する感じで)それを満たさないとき繰り下げて、また最初からやり直す。最下位の桁を3で割って切り上げたものを出力する。WAだけど、わかんなかったので仕方ない。これを提出するくらいしかやることがないくらいわからなかった。答えが小さくなりそうな雰囲気はあったけど、それも証明できないので一応charからintにしてみたり。

(追記)42で一の位だけ見て1を出力するコードになってた。更新しながら使ってた下限の最大値を出力する。なんかAC。解説は頑張って読んだけど自分には難しかった。既視感は一応あるが、あれでO(log(N))になるの自分の感覚にない(上で爆発って書いたやつ(これも桁を分離して考えてて最近やった桁DPに引きずられてるんだよなあ))。

D - Inc, Dec - Decomposition

自分の実力では解けそうにない見た目をしている。とりあえず、BとCがどんどん離れていってしまいそうなのはわかる。差をできるだけ小さく保ちたいので、Aが大きくなったらBだけをいじり、Aが小さくなったらCだけをいじる。すると、このBCをいくつずらしたら最小になるかという問題になる。片方だけなら二分探索できるけど、BとCの和なのでたぶんダメ。前後50見たけど提出して半分くらいWA。正や非負の個数でどれだけ改善/悪化するか決まるんだけど、例えばB側でどこまで負にするか固定して考える?時間かかりそうで諦めたけど時間あったとしてもだめかあ。

(追記)非負整数tに対してBからt引いてCにt足すことを考える。グラフを描くとスコアは折れ線になっているのでその折れているところだけを探しても最小値は見つかる。全探索できそうだ。BCを(Cは符号反転してから)ソートする。累積和を計算しておく(ここがマジでオーバーフローギリギリ)。Bが { 1, 3, 5, 7 } のとき、t=5なら5以上の要素についてはフルに5ずつ絶対値を減らせる(5以上が何個目からかは二分探索(しゃくとりもできそうではあるけどさすがにね?))。5未満のとき、5以上の場合と比べて1減る毎に2だけ損する。全部tだったケースと比べてどれだけ減ってるかを累積和で計算する。アイデアはわりとすぐ思いついたけど、実装にかなり時間をかけた。解説は難しくてわからん。CDの解説異常に難しい(前提とする数学のレベルが高い気がする)。