Library Checker をやるぞ!
このスクラップは
Library Checker のメモ置き場です。アルゴリズムの学習は 未知盆栽.hs でやっています。
60 問解けたら (今日の) ランキング 100 位なので、そこを目指そうと思います。
ローカル環境で verify するには (Haskell)
verifycation-helper (oj
) を使うとローカルで verify できます。 Haskell のデフォルトの実行コマンドは runghc
のため、コンパイル実行には追加設定が必要です。
-
Online Judge Verification Helper の細かい仕様
実行コマンドの変更方法が載っています。 -
toy-lib/verify
:/script/verify
コマンドから実行し、compile
,build
を呼び出す運用です。パスがややこしい。
Sample
入出力の高速化を図ります。
A + B
これは本当にサンプルでした。
main=interact$show.sum.map read.words
Many A + B
291 ms. String
縛りだと TLE になるため bytestring
パッケージを導入します。
入力を速くするためには、どうしても ByteString
の内部に触れる必要があります。 Unboxed tuples の嵐になるため飛ばしています。
出力には ByteStringBuilder
が効きます。中身は LazyByteString
の連結リスト (?) で、バッファを経由せずに直接 stdout
に書き込まれるようです。正格な ByteString
を結合していくと ByteStringBuilder
の結合は
Data Structure (1)
データ構造の問題はベンチマークテストを兼ねており、基本装備を強化できます。中盤から木が増えそうです。
Associative Array
436 ms. maspy さんの HashMap
(Int
-> a
のみ) を写経しました。座標圧縮 (
TODO: 任意のデータ型をキーとしたいです。
Predecessor Problem
2 分木のベンチマークができます。
-
IntMap
: 2256 ms
心もとないスピードです。 -
DenseIntSet
: 582 ms
maspy さんのFastSet
こと64 分木、もとい hibitset を写経してみました。引数はInt
のみで定義域は[0, n)
に限定されます。なぜかそこまで速くありません。 TODO:bitvec
に替えてみたいです。 -
Splay 木 (unboxed vector 製): 2086 ms
IntMap
よりも僅かに速いものの、イマイチ。
Double-Ended Priority Queue
-
IntMap
ベースのMultiSet
: 910 ms
やはり遅いです。座標圧縮して 64 分木を使ってみる? maspy さんのDouble_End_Queue
を見てみたいです。
Unionfind
84 ms. 特に問題無し!
Static Range Sum
209 ms. 累積和の取得演算子 +!
をテストできました。
Static RMQ
310 ms. 正格セグメント木 (区間取得 (可換))
Point Add Range Sum
249 ms. 正格セグメント木 (1 点更新、区間取得 (可換)) 。
Point Set Range Composite
454 ms. 正格セグメント木 (1 点更新、区間取得 (非可換)) 。
Range Affine Point Get
911 ms. 遅延セグメント木 (区間更新、 1 点取得 (可換)).
Range Affine Range Sum
273 ms. 遅延セグメント木 (区間更新、区間取得 (可換)). Vertex Set Path Composite の affine 変換とは合成の順序が逆です。どちらかの順序に実装を合わせて、もう一方の問題では Dual
モノイドに包むのが良さそうです。
Range Set Range Composite
2,778 ms. 遅延セグメント木 (区間更新、区間取得 (非可換)).
Range Chmin Chmax Add Range Sum
225 ms. Segment Tree Beats!
- https://smijake3.hatenablog.com/entry/2019/04/28/021457
- https://github.com/maspypy/library/blob/ae783f093ffac1b12c584fb599865f25fa2260e0/ds/segtree/segtree_beats.hpp
- https://github.com/maspypy/library/blob/ae783f093ffac1b12c584fb599865f25fa2260e0/ds/segtree/beats_summinmax_chminchmax.hpp
Range Kth Smallest
356 ms. 最小限の Wavelet Matrix
Data Structure (2)
Point Set Range Sort Range Composite
Range Reverse Range Sum
856 ms: 反転可能 splay tree. 遅延評価の抽象化に無駄があって 100ms ほど余分に遅いです。
Dynamic Sequence Range Affine Range Sum
3,376 ms: 遅延伝播反転可能 splay tree.
..
Queue Operate All Composite
187 ms. Stack で SWAG. Deque 版で解くと 219 ms でした。
Deque Operate All Composite
220 ms. Deque で SWAG.
Static Range Frequency
1,350 ms. Wavelet Matrix. IntMap
解法とほぼ同速なのがショックです。
Static Range Count Distinct
1,378 ms. Wavelet Matrix. Verify というか応用的な問題です。元ネタとして D-Query という問題があるようです。
Data Structure (3)
Static Range Mode Query
..
Rectangle Sum
1,981 ms. Segment Tree on Wavelet Matrix. なんか遅いんですよね……。
Point Add Rectangle Sum
969 ms. Segment Tree on Wavelet Matrix. やっぱり遅い気が。
..
Persistent Queue
268 ms. クエリを順番に処理すると GC で死ぬので、 DFS しつつ最小限の履歴を持ちます。
Persistent Unionfind
578 ms. IntMap 製 Union-Find で一応解けます。
New
Unionfind with Potential
126 ms. 重み付き Union-Find (可換群)
Unionfind with Potential (Non-Commutative Group)
319 ms. 重み付き Union-Find (非可換群)
Graph (1)
グラフ序盤では、重み有りグラフや経路復元を要求する問題が多いです。グラフ抽象化を見直す機会となります。
Cycle Detection (Directed)
391 ms. 閉路検出 (有向グラフ)
Cycle Detection (Undirected)
340 ms. 閉路検出 (無向グラフ)
Shortest Path
268 ms. Dijkstra 木。 Dijkstra の引数は Sum
, Max
, Min
をまとめる何かにした方が良い気がしています。
Strongly Connected Components
398 ms. SCC. 高速化したいです。
Tree
木ではとにかく HLD が強いようです。 maspy さんのライブラリにおいても単なる Tree
が HLD を持ちます。やはり HLD が木を解く主要なデータ型と言えそうです。
Tree Diameter
260 ms. こういうのが一瞬で求まる環境を作っておくのが良いですね。
Lowest Common Ancestor
430 ms. HLD. ダブリングより HLD の方が速かったです。ダブリング (binary lifting) は、ライブラリとしてはアンチパタンかもしれません (mod 上の逆元 → exgcd、 LCA → HLD, suffix array → SA-IS など)
Jump on Tree
552 ms. HLD. Vertex Add Path Sum 等で作った簡素な HLD が魔改造される問題です。まだ強くなるというのか……!
Frequency Table of Tree Distance
未回答
Rooted Tree Isomorphism Classification
未回答
Tree Path Composite Sum
339 ms. 辺に重みがあるタイプの全方位木 DP です。 Op
と Acc
の関係は既存コードのままに、 onEdge :: op -> (Vertex, w) -> op
を追加しました。
Vertex Add Path Sum
646 ms. HLD (頂点に重み、可換).
Vertex Set Path Composite
431 ms. HLD (頂点に重み、非可換). 木において辺の重みを頂点に載せるテクニックがあり、 ABC 294 - G も重要です。 maspy さんの Tree_Monoid
を写経して実装しました。
Vertex Add Subtree Sum
404 ms. HLD. Index 後の頂点 (頂点’) について、部分木の頂点' はすべて連続しているため、部分木のサイズを記録しておけば部分木の可換モノイドを一括で畳み込めます。辺を畳み込む場合もほぼ同様でしょう。
..
Dynamic Tree Vertex Add Path Sum
1,118 ms. LCT, 可換モノイド。辺の追加 (link), 削除 (cut) とパスの畳み込みをやります。パスの畳み込みは preferred path の根における集約でした。非可換モノイドに非対応ならば 150 ms 程度速くなります。
Dynamic Tree Vertex Set Path Composite
1,749 ms. LCT, 非可換モノイド。ノードに逆向きの畳み込みも持たせます。
Dynamic Tree Vertex Add Subtree Sum
1,470 ms. LCT, 部分木の畳み込み。これまでは集約を同じ preferred path 内のノードに限定していましたが、 path-parent も集約の対象とします。
Convolution
大前提が DFT! 連続信号を離散化し、周期関数に拡張した上で高周波成分をカットすると、元の信号を N 個の周波数成分で表現できます。理論が重い。
Convolution
1,285 m4 NTT. 大変過ぎた上に、まだ 10 倍高速化できるようです。
Numeric Theory
大の苦手分野かもしれません。
Sum of Floor of Linear
63 ms. Floor sum. 図を書いて辛うじて理解できました。辛過ぎます。
Floor sum においても離散化により周期性が生まれているようです。
Polynomial
何だろう。 1 問でも解ける日は来るのでしょうか。
Set Power Series
噂の形式的冪級数?
Enumerative Combinators
これは何でしょうか。
Linear Algebra
ジャッジ環境に線形代数ライブラリが無いこともあり、逆行列までは欲しいですね。
Matrix Product
5,333 ms. 行列積。意外にバグっていてショックでした。しかも遅い。 HasCallStack
を消すと 500 ms ほど速くなりました。
Matrix Product (Mod 2)
Bitset で 64x 高速化?
Pow of Matrix
4,453 ms. 行列累乗。 stimes の正格評価版を作って使います。
Determinant of Matrix
行列式
..
Rank of Matrix
階数
..
Inverse Matrix
逆行列
String
文字列も苦手です。高度な上に、要求に際限がありません。
Z Algorithm
22 ms. 小気味好い線形アルゴリズムです。使い方……?
Enumerate Palindromes
未回答
Suffix Array
215 ms. ダブリングで何とか。 SA-IS ……
Number of Substrings
203 ms. LCP Array. 応用?
..
Longest Common Substring
Suffix Array?