Codeforces Round 519 by Botan Investments

スポンサーリンク

A. Elections

総数が $2\times sum(A)$ を超えるようにする.

B. Lost Array

$k$ を決めたときの判定は簡単.すべての $k$ をそのまま試せばよいです.

C. Smallest Word

必ず aaaabbbb のタイプの文字列を得ることができます.同じ文字が塊になるように順に処理します.

D. Mysterious Crime

$0$ 行目の subarray の始点ごとに残せる最大長を求めます.

E. Train Hard, Win Easy

$M$ ペアについては単に答えから引くだけです.$i$ ごとに,$\sum_j\min(x_i+y_j,x_j+y_i)$ を求めるというのが問題です.$\min$ のどちらが小さいかは $x_i-y_i$ と $x_j-y_j$ の大小で決まるので,$x-y$ でソートしておけば単なる区間和の計算になります.

F. Make It One

メビウス変換を利用すれば,ちょうど $k$ 要素を選んで gcd を 1 にする方法は適当な mod で数えられます.これが $0$ かどうかで gcd を 1 にできるかの判定とします.

可能ならば答は非常に小さいです.$\{a_0\}$ からはじめて,各 $p\nmid a_0$ に対して $p$ の倍数ではない $a_i$ を追加していけばよいです.すると,その場合にちょうど $k$ 要素を選んで gcd を 1 にする方法も小さい(数百ビット以下)ので,30 bit 程度の素数を 5 個程度選べば理論保証ができます.mod 998244353 と mod 10^9+7 だけでも AC になりました.

G. Speckled Band

どの文字も異なる場合,答は $-1$ です.そうでないとき答は $4$ 以下です.LxMxR の形の substring があるからです.よって答が $1$ 以下,$2$ 以下,$3$ 以下であるかを判定すればよいです.

同じ証明で,左端の文字または右端の文字の出現回数が $2$ 以上ならば答は $3$ 以下です.そうでないとき,答が $3$ 以下であるかは LXXR の形になっているか(同じ substring の繰り返しを含むか)と同値です.そのためには各始点に対して XX の形の substring の終わる位置の最小値を求めておけばよく,https://judge.yosupo.jp/problem/runenumerate を利用すればできます.

答が $1$ 以下かどうかは長さの素因数 $p$ をとって $p$ 個の繰り返しであるかを判定すればよいです.

あとは答が $2$ 以下かどうかの判定です.これは結局,XXY, XYX, YXX のいずれかの形になりますかということです.このうち XXY, YXX に対しては固定された始点・終点に対する XX の形の substring の最小長さを求めておけばおく,やはり https://judge.yosupo.jp/problem/runenumerate でできます.

一番難しいのが XYX の形であるかどうかです.つまり与えられた substring が border を持つか否かです.これは解説を見ました.suffix array 等の前計算のもと,substring の最短 border をクエリ $O(\sqrt{N})$ 時間で求められます.

まず適当な $K$ に対して,長さ $K$ 以下の border があるかどうかを調べます.$O(K)$ 時間.

これがなかったとします.border の border は border なので,最短 border は borderless です.borderless な substring は,その occurrence 同士に共通部分がありません.すると,長さ $K$ 以上の borderless string の $S$ における occurrence は高々 $N/K$ 回しかないことが分かります.

したがってこの場合,$S[L:N)$ との lcp が $K$ 以上であるような $S$ の suffix は $N/K$ 個以下です.これらは suffix array で $S[L:N)$ の近傍を探索すれば列挙可能で,これらが答の候補になります.これらを計算すれば全体で $O(K+N/K)$ 時間で,$K=\sqrt{N}$ ととれば $O(\sqrt{N})$ 時間です.

CodeForces
スポンサーリンク
シェアする
maspyをフォローする
maspyのHP
タイトルとURLをコピーしました