2800 到達時の記録 AtCoder で rating が 2800 に到達しました - noshi91のメモ
AtCoder Performances, AtCoder Scores, rating-history などがサービス終了しており寂しさを感じました。
2800 到達時の記録 AtCoder で rating が 2800 に到達しました - noshi91のメモ
AtCoder Performances, AtCoder Scores, rating-history などがサービス終了しており寂しさを感じました。
Lagrange inversion theorem - Codeforces
[Tutorial] Generating Functions in Competitive Programming (Part 2) - Codeforces
注意: 一応証明したつもりですが、係数環を一般の可換環に取るところが怪しいです
\begin{alignat}{2} \lbrack x ^ n \rbrack G(x) & {} = \frac{1}{n} & \lbrack x ^ {- 1} \rbrack & F(x) ^ {- n} \cr & = {} & \lbrack x ^ {- 2} \rbrack & F(x) ^ {- n - 1} F'(x) \cr & = \frac{1}{n} & \lbrack x ^ {n - 1} \rbrack & \phi(x) ^ {n} \cr & = {} & \lbrack x ^ {n - 1} \rbrack & \phi(x) ^ {n - 1} (\phi(x) - x \phi'(x) ) \end{alignat}
\begin{alignat}{2} \lbrack x ^ n \rbrack G(x) ^ k & {} = \frac{k}{n} & \lbrack x ^ {- k} \rbrack & F(x) ^ {- n} \cr & = {} & \lbrack x ^ {- k - 1} \rbrack & F(x) ^ {- n - 1} F'(x) \cr & = \frac{k}{n} & \lbrack x ^ {n - k} \rbrack & \phi(x) ^ {n} \cr & = {} & \lbrack x ^ {n - k} \rbrack & \phi(x) ^ {n - 1} (\phi(x) - x \phi'(x) ) \end{alignat}
\begin{alignat}{2} \lbrack x ^ n \rbrack H(G(x) ) & {} = \frac{1}{n} & \lbrack x ^ {-1} \rbrack & H'(x) F(x) ^ {- n} \cr & = {} & \lbrack x ^ {-1} \rbrack & H(x) F(x) ^ {- n - 1} F'(x) \cr & = \frac{1}{n} & \lbrack x ^ {n - 1} \rbrack & H'(x) \phi(x) ^ {n} \cr & = {} & \lbrack x ^ {n} \rbrack & H(x) \phi(x) ^ {n - 1} (\phi(x) - x \phi'(x) ) \end{alignat}
について
\begin{alignat}{2} \lbrack x ^ {- 1} \rbrack W(x) H(G(x) ) = \lbrack x ^ {-1} \rbrack & W(F(x) ) H(x) F'(x) \end{alignat}
\begin{align} \lbrack x ^ {- 1} \rbrack F(x) ^ n F'(x) = \begin{cases} 1 \quad & (n = - 1) \cr 0 \quad & (n \neq - 1) \end{cases} \end{align}
\begin{align} G(F(x) ) &= x \cr H(G(F(x))) &= H(x) \cr (H \circ G)'(F(x)) F'(x) &= H'(x) \cr (H \circ G)'(F(x)) F(x) ^ {- n} F'(x) &= H'(x) F(x) ^ {- n} \cr \lbrack x ^ {-1} \rbrack (H \circ G)'(F(x)) F(x) ^ {- n} F'(x) &= \lbrack x ^ {-1} \rbrack H'(x) F(x) ^ {- n} \cr n \lbrack x ^ n \rbrack H(G(x) ) &= \lbrack x ^ {-1} \rbrack H'(x) F(x) ^ {- n} \cr \end{align}
\begin{align} G(F(x) ) &= x \cr H(G(F(x))) &= H(x) \cr H(G(F(x) ) ) F(x) ^ {- n - 1} F'(x) &= H(x) F(x) ^ {- n - 1} F'(x) \cr \lbrack x ^ {-1} \rbrack H(G(F(x) ) ) F(x) ^ {- n - 1} F'(x) &= \lbrack x ^ {-1} \rbrack H(x) F(x) ^ {- n - 1} F'(x) \cr \lbrack x ^ n \rbrack H(G(x) ) &= \lbrack x ^ {-1} \rbrack H(x) F(x) ^ {- n - 1} F'(x) \cr \end{align}
単調増加な正実数列 によって定義される関数 は Monge であることを示せ。
https://x.com/tempuracpp/status/1854498278190285099
区間の平均値 を定義すると、 である。
\begin{align} & & f(l _ 0, r _ 0) + f(l _ 1 + r _ 1) & \leq f(l _ 0 , r _ 1) + f(l _ 1, r _ 0) \cr \iff & & (r _ 0 - l _ 0) \sqrt{\mathrm{Av g}(l _ 0 , r _ 0)} + (r _ 1 - l _ 1) \sqrt{\mathrm{Av g}(l _ 1 , r _ 1)} & \leq (r _ 1 - l _ 0) \sqrt{\mathrm{Av g}(l _ 0 , r _ 1)} + (r _ 0 - l _ 1)\sqrt{\mathrm{Av g}(l _ 1 , r _ 0)} \cr \iff & & \frac{ (r _ 0 - l _ 0) \sqrt{\mathrm{Av g}(l _ 0 , r _ 0)} + (r _ 1 - l _ 1)\sqrt{\mathrm{Av g}(l _ 1 , r _ 1)} }{r _ 0 + r _ 1 - l _ 0 - l _ 1} & \leq \frac{ (r _ 1 - l _ 0) \sqrt{\mathrm{Av g}(l _ 0 , r _ 1)} + (r _ 0 - l _ 1)\sqrt{\mathrm{Av g}(l _ 1 , r _ 0)} }{r _ 0 + r _ 1 - l _ 0 - l _ 1} \end{align}
両辺とも の凸結合の形であり、引数の凸結合を取ると一致する。 の単調性から左辺のほうが偏った凸結合になっており、 が凹関数であることから偏った凸結合ほど小さくなるため求める不等式を得る。
問題設定を連続版にする。 すなわち、 を単調増加な関数として、 の Monge 性を示す。 ここから元の問題の結果も導かれることは明らか。
が示せれば、 において積分することで が示され、求める不等式を得る。
まず について偏微分すると が分かる。 と定義し、これを利用して について偏微分すると となる。 は区間の平均値を意味しているから、 の単調性と合わせると以下の事実が言える。
つ目の事実から、 が分かる。 これと つ目の事実を合わせると、 が従う。
グラフ理論ではないしグラフですらない。列。
両端にダミーの頂点を追加すると、操作 は操作 で表現できる。 よって操作 だけを考えればよい。 最初の頂点も操作 で作ることにすれば、問題は以下のように言い換えられる。
頂点 つが辺で結ばれている。 操作 を好きな回数繰り返して両端以外の全ての頂点を白くするとき、パスの長さ (辺の本数) として取り得る値は何か。
で と の長さ全てが作れることは簡単に分かる (辺の本数で長さを定義したので ずれているが本質ではない)。 必要性を示す。
つの頂点が辺で結ばれており、何らかの色が付いている。 操作 を好きな回数繰り返して両端以外の全ての頂点が白くなったとき、以下のいずれかに該当する。
長さが で、両端はいずれも偶数回色が変化した
長さが で、両端はいずれも奇数回色が変化した
パスの長さについての帰納法を用いる。 パスの長さが の場合は自明である。
パスの長さが 以上の場合、少なくとも 回は操作をしている。 最初の操作によって追加された頂点を とする。 以降の操作は より左に行われるものと より右に行われるものに分けられる。 最終的に両端以外が白になっていることから、 の左右でそれぞれ帰納法の仮定が適用できる。
最終状態において より左の部分 ( を含む) を 、 より右の部分 ( を含む) を とする。 のそれぞれに帰納法の仮定を適用すると、 が白になっていることから、両者とも に該当するか、両者とも に該当するかのいずれかである。
よっていずれも定理の主張に該当する。
操作を最初の 回とそれ以降とに分けるのはポリアの壺にも有効な考え方である。 尤も、ポリアの壺には一旦全ての球を区別するという簡潔な解法が存在するが。
無向グラフ , 非負の辺重み , 始点 , 終点 が与えられる。 各 について、 上での 最短路長を求めよ。
この問題を の時間計算量で解くアルゴリズムを説明する。
本質的に同じ問題が https://codeforces.com/contest/1163/problem/F で出題されており、解説するアルゴリズムは tutorial にあるものと同じである。 ただしこの tutorial には証明がないため注意。
議論を簡易にするため、まず辺重みは を含まないものとする。 このとき、以下のアルゴリズムが正しく答えを計算する。
まず、 を始点とする最短路木 と を始点とする最短路木 をとる。 ただし、両者で パス部分が一致するようにし、それを とおく。 を取り除いたときの最短路長は明らかに である。
各辺 に対し以下の処理を行う。
ただし、 は順序対として扱う、すなわち にも上記の処理を行うものとする。
処理が全て終わったとき、候補の中で最短のものが求める答えである。
候補の中での最短の計算は、双対セグメント木を使ったり、std::set
などのデータ構造を使って imos 法のような処理を行えばよい。
辺 を固定し、 に関する答えが正しく計算されることを示す。
任意の頂点 に対し、以下の両方が成り立つことはない。
同時に成り立つ が存在すると仮定する。 パスと パスが で交差しているが、 の前後でパスを組み替えると、合計長が真に短いパスの組が得られるため、それぞれが最短路だったことと矛盾する。 を使用したことに注意せよ。
における パスが を 含まない ような を 、 における パスが を 含まない ようなものを と呼ぶことにする。 補題より、全ての頂点は であるか である。 両方に該当する頂点は好きな方に割り当てておく。
における 最短路を つとり とする。 は であり は であることから、 上の辺 であって が , が であるものが存在する。 また、 の関係から である。 するとアルゴリズム中でこの に対して構成されるパスは を通らず、かつ と同じ長さであるため、 に対する答えが正しく計算される。
この場合、 と の取り方によってはアルゴリズムが誤った答えを返すことがある。 補題が成り立つように適切に取ればよいが、最も証明が明らかな方法は重み の辺を重み にすることである。
有向グラフに対してはこのアルゴリズムは正しく動作しない。 証明において破綻するのは、補題で パスと パスの組み換えを行った部分である。
要素の集合を つに分割することを 回行って、どの 要素もどこかで分離されているようにすることができる。 向きの付いた分割についても同様の問題を考え、それぞれの構成法と最適性を示す。
無向グラフ があり、各辺には正の重みが付いているとする。 が与えられるので、 の条件下で 間の距離の最小値を求めよ。
この問題は Dijkstra 法に少し手を加えると で解くことができるが、ここではその解法は思い浮かばなかったことにする。
を始点とする Dijkstra 法を行うと、どの に対しても への距離は となってしまうため上手く行かない。 そこで を取り、 を始点とし を終点とする距離を求める。 もし最適な が によって分離されているなら、すなわち を満たすなら、これで最適値が得られる。 を一様ランダムにとれば の確率でこれは達成されるが、決定性アルゴリズムを得たい。 定式化すると以下のようになる。
集合 に対し、以下の条件を満たす集合族 を構成する。
は に対しどこまで小さくできるか?
各 に対し、 と定義する。 すると問題の条件は、任意の に対して と言い換えることができる。 なら鳩の巣原理によりこの条件は満たされることはなく、逆に ならば各 が の相異なる部分集合になるように を定めることができる。 よって が最適である。
元の問題例は で解けることになる。
この節は ICPC 2023 World Finals Luxor に出題された問題の解法を基に執筆しています。
有向グラフ があり、各辺には正の重みが付いているとする。 が与えられるので、 の条件下で の距離の最小値を求めよ。
有向グラフになったため、最適な に対し を満たす必要がある。 定式化すると以下のようになる。
集合 に対し、以下の条件を満たす集合族 を構成する。
は に対しどこまで小さくできるか?
前節と同様に、各 に対し と定義する。 すると問題の条件は、任意の に対して と言い換えることができる。 を固定した際にこのような が最大でいくつ取れるかという問題の解答は Sperner の定理として知られており、 として大きさ の の部分集合を選べばよい。 したがって、 となる最小の が の最小値である。 であり、例えば で 程度まで構成できる。
文字集合を とする文字列 と がある。 の長さ の連続部分列のそれぞれについて、 にマッチするか判定せよ。 ただし文字列がマッチするとは、それぞれの文字列中の を好きな文字に置き換えたときに両文字列が一致することを指す。
文字列 と がマッチすることと が同値である。 したがって、各 について を計算できればよい。 これは括弧を展開して積和形にし、それぞれの項については適切な列を FFT を用いて畳み込めばよい。 時間計算量は 。
前述した解法は最終的に か判定したい値が 程度まで大きくなり得る。
\begin{align} S ' _ i := \begin{cases} 0 \quad & ( S _ i = 0 ) \cr 1 \quad & ( S _ i \neq 0 ) \end{cases} \cr T ' _ i := \begin{cases} 0 \quad & ( T _ i = 0 ) \cr 1 \quad & ( T _ i \neq 0 ) \end{cases} \end{align}
と定義すれば、 で判定しても問題ない。 これで まで削減された。 ちなみに とするとこの値は 以下になる。
素数 と一様乱数 を用いて、 を判定してもよい。 このとき の各連続部分列について、マッチしていると誤って判定される確率は 以下である。 が大きくても値域の問題が発生しないことと、項を展開すると つしかないため畳み込みの回数が減るという利点がある。
これらのアルゴリズム内では、 を各 について求めるために畳み込みを用いる。 これは を反転して通常の畳み込みを行えばよいのだが、畳み込んだ結果のうち先頭 項と末尾 項は必要がない。 よって巡回畳み込みでこれらの部分が重なっても問題なく、畳み込みの長さを短くすることができる。
アルゴリズム中では 回の畳み込みを行い、その和だけに興味がある。 よってそれぞれの畳み込みにおいて IDFT を行わず、全部足し合わせて最後に 度だけ IDFT を行うことで定数倍高速化になる。 ボトルネックには関係ないと思われるが、IDFT の後の規格化も非零判定だけなので必要ない。
側にワイルドカードがない場合、常に である。 すると を積和形にした際に現れる つの項の内 つは に依存しない値になり、その総和は定数となる。 側にワイルドカードがない場合も同様の議論により、累積和で つの項は計算できる。 前述した乱択の場合も、 つの畳み込みが つに削減される。
判定するべき連続部分列のうち最初の 個を判定するためには の先頭 文字があれば十分であり、これを切り出して今までのアルゴリズムを適用すれば で判定できる。 この調子で 個ずつ判定すると全体で となる。 一度に判定する量は の何倍かの範囲で調整した方が定数倍が良いかもしれない。
乱択ベース、巡回畳み込みと線形性の高速化あり
https://judge.yosupo.jp/submission/211249
[1] Clifford, P., & Clifford, R. (2007). Simple deterministic wildcard matching. Information Processing Letters, 101(2), 53-54.
[2] Clifford, R., Efremenko, K., Porat, E., & Rothschild, A. (2009, January). From coding theory to efficient pattern matching. In Proceedings of the twentieth Annual ACM-SIAM Symposium on Discrete Algorithms (pp. 778-784). Society for Industrial and Applied Mathematics.