ABC 363

ABC 363 に参加しました。回分回でした。爆死された方が多かったようです。

Table 1: 体感 Diff
問題 A 問題 B 問題 C 問題 D 問題 E 問題
予想 10 200 600 1,500 1,000
実際 18 32 602 975 1,307

A 問題

\(A\) を 100 の倍数に切り上げたとき、元の数よりどれだけ大きくなるか。 \(100 - a\%100\) で解けます。

main=print.((100-).(`mod`100))=<<readLn

B 問題

愚直テストを 2 分探索しました。

今考えると、降順ソートして前から P 番目の人に注目するのが良さそうです。

import Data.List;main=interact$show.f.map read.words;f(n:t:p:l)=max 0$t-sort l!!(n-p)

よくあるソートは \(O(N \log N)\) ですが、 selectBy を使えば \(O(N)\) で解けるそうです? CS をやった人ならピンと来るかもしれません。

そういえば Data.Vector.Algorithms.Intro.selectBy を使うとABC363-BはO(N) で解けますね

— 符号/gksato (@Fine_sugar_hill) July 20, 2024

C 問題

\(O(N \cdot N!)\) が通るため、すべての (ユニークな) 順列を全探索します。 vector の nextPermutation で解けそうですね。

実際は TLE します。 2014 年の TODO が原因だったので、 vector に PR を投げました

ちなみにstrictness analysisでうまくいかないのは一般のPrimMonad だからっぽいので、そこにbang patternを突っ込む代わりに 処理開始時に stToPrim を噛ませても解決します:https://t.co/trLQ7ZvTX2

— 符号/gksato (@Fine_sugar_hill) July 21, 2024

stToPrim でさらに速くなります。型クラスを使うと遅くなる (*) ので、モナドのインスタンスを ST に確定させた方が速いんですね。勉強になりました。

(*): 正確性解析や辞書渡しが原因

辞書順列を列強する lexPerm で upsolve しました。本来は軽い問題ですね。

  -- p の定義は省略
  printBSB $ V.length $ V.filter p $ lexPerms xs

D 問題

難しくないですか? 考察中です。

E 問題

ヒープで解きます。 cojna さんの BinaryHeap は最高だぜの問題でした。

Misc

ビルド環境の改善

自作ライブラリを Main.hs に埋め込むのを止め、外部ライブラリとして参照する形に変更しました。例: 直近の Main.hs, 提出 (埋め込み)

プロジェクトファイルはこんな感じです:

packages:
  ./abc363.cabal
  -- 絶対パス (仮)
  ~/dev/hs/toy-lib/toy-lib.cabal

constraints: (
  -- debug ログ ON
  toy-lib +debug
common deps
  build-depends:
    , adjunctions                    ^>=4.4.2
    -- ~~
    , toy-lib
    -- ~~

提出直前にライブラリを埋め込んで .submit.hs を作成します。提出ファイルも変更しました:

{
    "task": {
        "program": [
            "Main.hs"
        ],
        "submit": ".submit.hs"
    }
}

初回ビルドが遅いので、 Nix か何かでビルドキャッシュを共有したいところです。

コンテスト用コードの短縮

全ライブラリの埋め込みを止め、指定モジュールのみ埋め込むことにしました。 Haskell longest コードゴルフ王者、引退です。

-- {{{ toy-lib import
import ToyLib.Contest.Prelude
-- import ToyLib.Contest.Bisect
-- import ToyLib.Contest.Graph
-- import ToyLib.Contest.Grid
-- import ToyLib.Contest.Tree
import ToyLib.DP
-- }}} toy-lib import

いずれ使用モジュールのみ自動的に埋め込むようにしたいです。