ABC 380
ABC 380 に参加しました。
問題 | A 問題 | B 問題 | C 問題 | D 問題 | E 問題 | F 問題 | G 問題 |
---|---|---|---|---|---|---|---|
提出 | AC | AC | AC | AC | AC | - | AC |
予想 diff | 40 | 100 | 200 | 1,200 | 1,500 | 2,000 | 1,600 |
実際 diff | 16 | 27 | 223 | 849 | 1,230 | 1,769 | 1,995 |
A 問題
6 桁の整数が与えられる。 (1, 2, 3)
の出現回数がそれぞれ
(1, 2, 3)
回であるか判定せよ。ソートして比較します。
import Data.List;main=interact$y.sort;y"122333\n"="Yes";y _="No"
B 問題
正規表現 (ERE) で ^\|(-+\|+)+$
にマッチする文字列が与えられたとき、それぞれの
-
の長さを求めよ。連続した文字を group
関数でまとめます。
import Data.List;main=interact$unwords.map(show.length).filter((=='-').head).group
C 問題
正規表現 (ERE) で ^(0|1)+$
とマッチする文字列を連長圧縮したとき、
k
番目の 1
の『塊』を 1 つ手前の
0
の塊と入れ替えよ。
k
番目の 1
の塊を累積和で見つけました。なかなか大変です。
solve :: StateT BS.ByteString IO ()
solve = do
(!n, !k) <- ints2'
!s <- line'
let spans = V.fromList $ BS.group s
let nSpans = V.length spans
let csum = U.scanl1' (+) . U.convert $ V.map (subtract (ord '0') . ord . BS.head) spans
let ik = fromJust $ U.elemIndex k csum
let is = U.generate nSpans id U.// [(ik - 1, ik), (ik, ik - 1)]
putBSB . V.foldMap showBSB . V.backpermute spans $ U.convert is
D 問題
文字列 S
に対し、写像 S → ST
(T
: 大小文字を入れ替えた
S
) を繰り返し適用したとき、 \(\{K_i\}_i\) 番目の文字を求めよ。
生成される文字列の列は STTSTSST..
です。これを 01101001
と見て
OEIS で検索する
と、
Thue-Morse sequence
がヒットしました。
これを関数 t
として実装すると、大小文字を反転すべきかが分かります。したがって
\(K_i\) は次のように計算できます:
let f i =
let (!q, !r) = i `divMod` BS.length s
in if even (t q)
then BS.index s r
else flipCase $ BS.index s r
OEIS が無ければ自力で解けなかった可能性が高いです。危なかった。
E 問題
1xN
ピクセルが異なる色で塗られている。バケツツールで塗っていくとき、それぞれの色のピクセルが何ピクセルあるか追跡せよ。
区間を管理する構造体
、俗称区間をセットで管理するテクニックで AC
しました。これは区間書き込みのためのデータ構造で、区間の分割や連結を自動的に処理してくれます。そこにフック
(onAdd
, onDel
) を挟んでピクセル数の変化を追跡します。
solve :: StateT BS.ByteString IO ()
solve = do
(!n, !q) <- ints2'
qs <- U.replicateM q $ do
int' >>= \case
1 -> (1 :: Int,,) <$> int1' <*> int1'
2 -> (2,,-1) <$> int1'
cnt <- UM.replicate n (1 :: Int)
dm <- fromVecDM (U.generate n id)
let onAdd l r c = do
let dn = r + 1 - l
GM.modify cnt (+ dn) c
let onDel l r c = do
let dn = r + 1 - l
GM.modify cnt (subtract dn) c
res <- (`U.mapMaybeM` qs) $ \case
(1, !i, !c) -> do
writeMDM dm i i c onAdd onDel
return Nothing
(2, !c, !_) -> do
Just <$> GM.read cnt c
putBSB $ unlinesBSB res
PAST で高度典型をやったのが効いています。
F 問題
分からない……
G 問題
順列 が与えられる。長さ
K
の区間をランダムに選び、ランダムにシャッフルするとき、転倒数の期待値を求めよ。
シャッフルした範囲は、座標圧縮すればランダムな順列です。この転倒数の期待値は \(\frac {k(k -
1)} {4}\) になることが知られており、幅 \(K\)
の窓で転倒数の期待値を求めていくと解答できます。
Misc
ac-library-hs
の進捗
API ドキュメントや doctest
を追加しました。 11 月中に残るモジュールを実装し、
12 月中にベンチマークテストを実施できればと思います。
現在は suffix array を実装 (写経) していますが、バグ修正が進まず難儀しています。先に modint
や convolution を進めるべきかもしれません。
ラップトップの流行り
-
ゲーミング PC
最近の機種は相当イケているようです。重さと排熱・性能もそこそこ良いとか。
-
MacBook シリーズ
Mac のメモリは GPU メモリを兼ねるため、 AI に使えて良さそうですね。