ABC 376

Oct 20, 2024

ABC 376

ABC 376 に参加しました。

問題A 問題B 問題C 問題D 問題E 問題F 問題
提出4:4811:5219:4628:0949:3596:17
予想 diff1004004001,0001,2001,600
実際 diff192903667431,0632,089
Table 1: Diff 予想

226 位を取ってレーティング爆上がりです。

2024-10-20-rating.webp
Figure 1: 水ものレーティング

レーティングは適正値へ収束していくものなので、今後の大敗は覚悟します。悔しいだろうなー……

A 問題

単調増加数列の隣接項の差が cc 以上となるように項を間引く時、残った数列の最大の長さを求めよ。最終項を状態として畳み込みます。

main=interact$show.f.map read.tail.words;f(c:a:t:r)|t-a<c=f(c:a:r)|0<1=1+f(c:t:r);f _=1

B 問題

円環上の 2 物体に対し (物体, 移動先) の形で操作指令が与えられる。物体同士が衝突しない方向に指定の物体を動かして、操作指令を実行せよ。

円環を開きます。正方向の回転の可否を L<RL < R' かつ L<TL < T' となる最小の R,TR', T' (RRmodN,TTmodNR' \equiv R \bmod N, T' \equiv T \bmod N) を使って検証します。移動経路中に RR' があるかを inRange で判定すれば良いです。

負方向の回転も、同様に R<LR' < L かつ T<LT' < L となる最大の R,TR', T' を使って検証します 。

C 問題

NN 個の物体と N1N - 1 個の箱がある。 大きさ(物体) <= 大きさ(箱) となるようマッチングさせたとき、余る物体を可能な限り小さくせよ。

物体、箱をそれぞれ降順ソートし貪欲にマッチングすれば O(NlogN)O(N \log N) で解けます。未証明ですが。

-- 降順ソートされた [物体], [箱] を引数に ([余った物体],[余った箱]) を返す
eat :: [Int] -> [Int] -> ([Int], [Int])
eat = inner ([], [])
  where
    -- 物体が無くなった場合
    inner (!ls, !rs) [] restR = (ls, rs ++ restR)
    -- 箱が無くなった場合
    inner (!ls, !rs) restL [] = (ls ++ restL, rs)
    -- 箱も物体もある場合
    inner (!ls, !rs) (x : xs) (y : ys)
      -- 物体と箱がマッチする (物体 <= 箱)
      | x <= y = inner (ls, rs) xs ys
      -- 物体 x を余った物体の列に移動する
      | otherwise = inner (x : ls, rs) xs (y : ys)

D 問題

辺に重みを持つ有向グラフが与えられる。始点を頂点 1 として、最小閉路の長さを求めよ。

これが茶 diff なのはヤバい……。知っていたことは以下です:

DFS で全経路を見ると、明らかに TLE します (極端に言えば密グラフでは O(N!)O(N!) です) 。

多重始点の Dijkstra 法に帰着しました。すなわち頂点 1 から出た重み付き辺の集合 {(vi,wi)}i\{(v_i, w_i)\}_i を距離一覧やヒープの初期値とし、 Dijkstra 法を実施します。面白い!

公式解説 では、到達までの辺の数が KK となる頂点の集合を求めていました。これは難しい。

原案は evima さんでした。流石です。

E 問題

数列 {(Ai,Bi)}i\{(A_i, B_i)\}_i から KK 項を選ぶとき max{Ai}iiBi\mathrm{max} \{A_i\}_i \cdot \sum_i B_i を最小にせよ。

max{Ai}i\mathrm{max} \{A_i\}_i を全探索すると効率的に解答できます。すなわち {(Ai,Bi)}\{(A_i, B_i)\} を昇順ソートし、最初の KK 項を初期値に畳み込みます。状態としては iBi\sum_i B_i と multiset を持てば良いです。

けっこう難しい。

F 問題

B 問題の設定において、未指定の物体も動かしても良いとする。対象の物体は正方向と負方向のどちらに回せることになり、状態数が跳ね上がります (2Q2^Q) 。

その状態数を一定数のスロットに削減するのが DP! 2 物体の位置 (l,r)(l, r) をキーに Map で緩和すると O(NMlogN)O(NM \log N) ぐらいで解けました (運!) 。対象の物体は必ず同じ位置で止まりますから、 {(li,ri)}i=O(N)|\{(l_i, r_i)\}_i| = O(N) なんですね。

感想

Library Checker で閉路検出を経験したため、 D 問題をスムーズに考察できました。 Library Checker は良いぞー

Haskell

次の言語アップデート

ac-library-hs を作ります を投稿しました。リポスト・ライク等ありがとうございました!

関心のトピックは Issue に上げており 、開発が進めばまたブログにします。アドベントカレンダーにも投稿するかも。

案: プロジェクトを提出する

ジャッジに細工すれば、プロジェクトを丸ごと提出できるようにできます。確実に qualified import ができてアリ かも

{- AC_PROJECT src/MyLib/F.hs -}
module F (f) where

f :: Int -> Int
f = (+ 1)

{- AC_PROJECT app/Main.hs -}
import MyLib.F qualified as F

main :: IO ()
main = print $ F.f 1
Listing 1: 提出ファイル (イメージ)
.
├── app/
  └── Main.hs
└── src/
    └── MyLib/
        └── F.hs
Listing 2: 展開結果 (イメージ)

ac-library-hs で注目のパッケージ

本物のプログラマはHaskellを使う

本物のプログラマはHaskellを使う 。一連の記事が響くようになって来ました。 QuickCheck の記事などを読んでいます。

FastMutInt

StateT vs IORef: a benchmark - r/haskell にて FastMutInt を知りました。

Misc

Emacs 秋フェス

調子に乗って Emacs 秋フェス の登壇枠を取っていました。 leaf, Evil 辺りの当たり障り無い話をしようと思っています。 Embark, activities,bufler, popper など最近のパッケージを調べてみても良いかも。

Pixiv は怖過ぎるものの、エディタバーが楽しみ過ぎる!

我は陰の者、前日の Nix Meetup には参加できません。 Emacs 勉強会自体、ハードル高杉建築でした。