第6回では, 一般化された包除原理について扱います. 包除原理は「条件を 個以上満たすものの個数」を数え上げるものです. これを一般化すると, 「条件を 個以上満たす」「条件をちょうど 個満たす」や「条件を 個満たすものは が答えに足される」などもふつうの包除原理と同じノリで解くことができます.
この一般化は, 「二項変換」と関連があるのでそれについても述べます.
(追記 2023.08.03)練習問題を追加
↓記事が長すぎる!「もう解ける問題たち」を先に覗いた方がいいかも
普通の包除原理
有限集合 があるとします. としたとき,
が成り立ちます. 小さい例として, のときは
, のときは
となります.
補題
すべての正整数 に対して
が成り立ちます.( の場合は )
この補題がいつもの包除原理を支えています. この記事での包除原理の一般化は、ここの「補題」の式を変更するというイメージです.
証明 目的の式の左辺を とします. 二項定理より
となるので, が従います.
包除原理の証明
の要素 を任意にとります. に属する の個数がちょうど 個 とします. このとき, 個の共通部分のうち, が属するものの個数は 個である. よって,「 個違反には がかけられる」ことを考えて, の包除原理の式に対する寄与は
となりますが, これは補題より に一致します. よって結局
の右辺は, の要素の個数を数えるものになっています.
問題1
いつもの包除原理の例を見ます.
以下の正整数 であって, が のいずれかの倍数であるようなものは何個ありますか?
集合 を, 以下の正整数で の倍数全体, , も 以下の正整数でそれぞれ の倍数であるもの全体とします. すると, 求めたいものは です.
包除原理によって,
ですが, を最小公倍数を表すことにすると, それぞれについて
なので, も計算できます.
問題2
以下の正整数 であって, が のうち つ以上の倍数であるようなものは何個ありますか?
言い換えると, さきほどの において, 以下の正整数 であって, が の つ以上の要素であるようなものを求めればよいです. どうやって求めればよいでしょう?
いつもの包除原理のように,
を答えにしたくなりますが, これは誤りです. 実際は, は 回ではなく 回超過カウントされるので,
が求める答えです. このように, 個以上の集合に属する要素の個数を求めたい, というふうな場合は, ふつうの包除原理は使えないということがあります. そこで包除原理を一般化して同じように解くことができないかを考えました.
一般化包除原理
を満たす数列 があるとします. ( でも全体集合を定めれば OK です) このとき, を満たす数列 であって, 次の条件を満たすようにしたいです.
- 正整数 と有限集合 を任意にとる. の要素 であって, に属する の個数がちょうど 個であるようなものの個数を と書くと,
となる.
たとえば, ふつうの包除原理では , となります.
は によらない数列であることに注意します. そもそもこんなのは存在するのでしょうか? 実は数列 に対して, それに対応する唯一の数列 が存在します.
存在性と唯一性
包除原理の証明を参考にすると, の要素 を任意にとって, が属する の個数をちょうど 個 としたとき, 要素 は条件の右辺に対して
だけ寄与します. 条件の式の左辺 に注目すると, この式は になるべきです. よって
となります. これがすべての正整数 について成り立ってほしいのです. ここで と見ていくと,
となり, は の式で書けます. よって の順に の値を一意に決定することができます. この操作により まで見ると までが確定するので, は存在し, かつ一意です.
二項変換と逆変換
実は の関係式は二項変換と呼ばれます.( を仮定しません)
二項変換は 2 種類の定義がありますが, 「交代二項変換」ではない方(「単純二項変換」)で,
逆変換は,
となります. ただし,「単純二項変換」は『理系のための備忘録』で使用されているだけで, 一般的な単語ではないことに注意してください.
例 : b = (0,0,1,1,1,1,…)
として を求めてみます. この が求められれば, 問題 2 が一般に解けます.
の通常型母関数を , の通常型母関数を とします.
です. 目標は を求めることです.
より
より
より
より
より
ここまで来て, となりました. ここから, が続くと予想します.
さて, 少し脱線しますが の関係式を導いてみます. について,
が成り立って欲しいです. 式を変形すると, 畳み込みの式になっているので,
, すなわち
となります. これが と の関係を表す式となっています.
いま, の母関数は ですが,
について
そして について
となるので OK です!よって となり, 包除原理は次の形になります:
正整数 と有限集合 を任意とする. の要素 であって, に属する の個数が 個以上であるようなものの個数は,
となる.
つまり, ふつうの包除原理のときに「 個 () の共通部分には を掛ける」ところを, 「 個 () の共通部分には を掛ける」とすればよいです. この意味で, 「ふつうの包除原理と同じノリで解くことができる」と言い表しました.
二項変換の表示
二項変換には, 母関数に関する公式があります. これが便利です.
の通常型母関数を , の通常型母関数を とする. このとき,
が成り立つ.
の指数型母関数を , の指数型母関数を とする. このとき,
が成り立つ.
通常型母関数の証明(長い)
上の式を証明します. 上の式の右辺の の係数が の係数になることを示します.
に注意すると,
です. いま, いわゆる負の二項定理よりすべての に対して
が成り立ちます. を任意として, の係数には がすべて足されますから, の定義より
が成り立ちます. よって
が示せました. 下の式を示します. 上の式において と変換すると,
すなわち
となり, 示せました.
指数型母関数の証明(長くない)
を思い出します. の の次数に注目すると, 二項変換の定義によって
となり, これは に一致します.
a→b, b→a の N 次までの高速計算 (mod 998244353)
mod 998244353 で, 次までの二項変換を 時間で求めることができます.
指数型母関数の二項変換が簡単な式で書かれていることに注目します.
二項係数の前計算を行えば, 数列からその指数型母関数の 次までの係数を 時間で求められます. さらに指数型母関数の係数から数列の 項まで求めることも 時間でできます.
唯一 , を求めるのに畳み込みする必要があり, これには 時間かかります. 以上で二項変換が高速で求められました.
実装例 (c++)
cmb(n, k)
は二項係数, fact[i]
は階乗 , factinv[i]
は階乗の逆元 とします.
ftog
は に対する を, gtof
は に対する を返します.
vector<mint> ftog(vector<mint> &f){ int n = f.size(); vector<mint> F(n); for (int i=0; i<n; i++){ F[i] = f[i] * factinv[i]; } vector<mint> e(n); for (int i=0; i<n; i++){ e[i] = factinv[i]; } vector<mint> G = convolution<mint>(F, e); vector<mint> ret(n); for (int i=0; i<n; i++){ ret[i] = G[i] * fact[i]; } return ret; } vector<mint> gtof(vector<mint> &g){ int n = g.size(); vector<mint> G(n); for (int i=0; i<n; i++){ G[i] = g[i] * factinv[i]; } vector<mint> einv(n); mint par = 1; for (int i=0; i<n; i++){ einv[i] = par * factinv[i]; par *= -1; } vector<mint> F = convolution<mint>(G, einv); vector<mint> ret(n); for (int i=0; i<n; i++){ ret[i] = F[i] * fact[i]; } return ret; }
xK / (1-x)M 型の g について
の通常型母関数 が
()なら, の通常型母関数 は
となります.
これはおそらく最も使う場面が多いです.
- のときは, 「ちょうど 個の集合に含まれている要素」の個数を表します.
- のときは, ふつうの包除原理です.
- のときは, 「 個以上の集合に含まれている要素」の個数を表します.
追記:分母に が来ていますが, いわゆる負の二項定理というもので,
が成り立ちます.
もう解ける問題たち
問題3
個の正整数 が与えられます. 以下の正整数 であって, が のうち 個以上の倍数であるようなものは何個ありますか?
bit 全探索ですべてを調べます. lcm のオーバーフローに注意してください.
なので, とすればよいです.
追記:この場合, は については で, については が成り立ちます.
問題4
個の正整数 が与えられます. 以下の正整数 であって, が のうち奇数個の倍数であるようなものは何個ありますか?
なので,
です. よって, となります. これはすごいです!
問題5
個の正整数 が与えられます. 以下の正整数 について, を であって が の倍数であるものの個数とします. このとき, を で割った余りを求めてください.
問題6
の順列 であって, となる の個数が 個以下であるものの個数を で割った余りを求めてください.
これは一般化包除以外でも解けます. ただし, その場合は完全順列の個数を について列挙するのが一番簡単です.
練習問題
参考文献
Binomial transform - Wikipedia
通常型母関数の二項変換の参考にしました.
4.母関数の応用~二項変換とその逆変換 - 理系のための備忘録
指数型母関数の二項変換がすごく簡潔に表せることが書かれていました.