バーンサイドの補題について
はじめに
ABC198-F でバーンサイドの補題を知ったので、自分なりにまとめた記事です。
一応、群論の知識を仮定せずに読めるようにしてあるはずです。
用いる記法など
- : 整数全体の集合のこと。
- : 実数全体の集合のこと。
- : 集合 の要素数のこと。
- : 集合 と集合 の共通部分のこと。
- : が集合 の要素であるということ。
- : 基本的に と の積、 が集合である場合には 集合 のこと。
- : 空集合のこと。
群について
ある集合 があって、その集合の中の要素だけで行う二項演算 を考えます。 (つまり、 任意の に対して を満たしています。)
この時、 が以下のすべての条件
を満たすとき、 を群と呼び、 は演算 に関して群をなすと言います。
競プロer が知っていそうな代数的構造ナンバーワンのモノイド (セグ木に乗るやつです) に逆元の存在を付け加えた形になります。
代表的な群
★ 実数全体の集合 (加法について)
は加法について群をなします。群の定義を満たすか確認してみると、
逆元の存在: 任意の実数 に対し、 で、単位元 が であることからこれを解いて を得て、逆元が存在していることがわかります。
以上より、は加法に対して群をなすことが分かりました。この群のことを と書くこともあります。
加法に関して、実数全体の集合は上の三つ以外に大切な性質として交換法則 が成り立っています。
このように交換法則が成り立っている群のことを、アーベル群や可換群と呼びます。
★ 実数全体の集合から を除いたもの (乗法について)
は加法について群をなしますが、乗法についてだとそうはいきません。 を含めた場合に定義を満たすか確認してみましょう。
逆元の存在: 任意の実数 に対し、 となるような を考えると、一見 とすればよさそうに見えますが において は定義できません。
以上のことから、 は乗法について群をなしませんが、 から を除いた集合は乗法について群をなすことが分かりました。この群のことを と書くこともあります。
★ 次の置換の全体集合 (関数の合成について)
を順に代入していくとそれぞれ となりますが、 が全単射であったことを思い出すと、これは をそれぞれ異なる数字(元の数字と行き先の数字は同じでもよい)に置換しています。
このことから、上の条件を満たすような写像 のことを 次の置換と呼びます。
また、このような置換を
と書くこともあります。
例えば、 次の置換 を とすると、この置換は
と書くことができます。
ここで、 次の置換全体の集合を関数の合成に対して考えます。置換に対する関数の合成は例えば、
と定めたとき、
のように計算できます。上の二つの例と異なり、交換法則が成り立たない点に注意しましょう。
ここで、
単位元の存在: 次の置換 を、 とすれば、任意の 次の置換 に対し、 が成り立つため、単位元が存在しているとがわかります。
逆元の存在: 任意の 次の置換 について、 を を満たすすべての に対し、 となるように定めると、 が全単射であることから も全単射であり、 次の置換です。これより、逆元が存在していると分かります。
より、 次の置換全体の集合は関数の合成について群をなすことが分かりました。
このような群のことを と書き、 次対称群と呼びます。
同値関係
突然ですが、バーンサイドの補題への準備として、同値関係を扱います。
ある集合 上において、任意の の二つの要素同士についてある関係 が定義されているとき、
任意の に対して、 (反射律)
任意の に対して、 かつ ならば (推移律)
任意の に対して、 ならば (対称律)
がすべて成り立つのならば、このような関係を同値関係と呼びます。
同値関係という名前の通り、ある視点から見た際にその要素を同一視してもよいようなもの同士の関係であることが主です。
今後、群上で同値関係を定めたりします。
同値関係の例
★ 余りによる同値関係
を より大きい整数としたとき、整数全体の集合の要素に対して で割った余りが等しいような関係は同値関係です。このような同値関係を などと書きます。
皆さん などでお馴染みなのではないのでしょうか? 実際に同値関係か確認してみましょう。
- 反射律: 任意の整数 に対して、 ですから、反射律は成り立っています。
- 推移律: 任意の整数 に対して、 かつ であるとき、 ですから、推移律は成り立っています。
- 対称律: 任意の整数 に対して、 ならば ですから、対称律は成り立っています。
よって が同値関係であると分かりました。
剰余類
を演算 に関して群をなし、 を の部分集合であって に関して群をなすとします。*3このとき任意の に対して、
を による の左剰余類と呼び、
を による の右剰余類と呼びます。
剰余類による同値関係
には上の仮定が成り立っているとします。このとき以下が成り立つことが知られています。(証明略)
- 任意の に対し、 もしくは
- 任意の に対し、 もしくは
- 任意の に対し、
- 任意の に対し、
ここで、任意の に対し関係 を であることと定めると、これは同値関係です。 を であることとしても、同様に同値関係になります。
このことから、剰余類による同値関係は の要素に対してある種の分類を与えているとわかります。
剰余類による同値関係の例
★ 整数全体の集合と の倍数全体の集合からなる部分群による同値関係 (加法について)
は加法について群をなします。(実数の場合と同様です)
ここで、 を と定めると、これは の部分群になっています。
に対して上のような同値関係を考えましょう。加法は交換法則が成り立つので、 左剰余類と右剰余類のどちらを考えてもよいです。ここでは左剰余類を考えます。
少し考えると、 に対して であることと であることは同値です。 を示します。
適当に選んできた が であったとき、任意の について であるため、 と分かります。
したがって です。逆も仮定を から始めることで容易に示せます。
これより、 の による同値関係は上で考えた と同値と分かります。
また、この同値関係によって は三種類の集合に分けることができます*4。
このような剰余類による同値関係での分類の個数を と書き、部分群 の指数と呼びます。左剰余類と右剰余類による分類の個数は等しいことが知られており(後に証明します)、どちらか区別できなくてもよい記法になっています。
剰余集合
を群、 を の部分群とします。この時、
を左剰余集合、
を右剰余集合と呼びます。 これは先ほど を で分類していたのと同じことをしています。
実際、この定義において と置けば、 となって先ほどの分類と一致します。
ここで証明を保留した「左剰余類と右剰余類による分類の個数は等しい」、つまり を示しましょう。
これと同じような方法によって示せるものとして、 があります。概略としては、 を任意の に対して と定めて、これが全単射であることを示せばよいです。
ここで、 より、 は単射です。全射性は定義より明らかなので、 の全単射性が示せました。
また、剰余集合における基本的な定理として、以下があります。
証明
のとき主張は明らかであるため、そうでないときのみを示せばよいです。
となるように を取ると、 です。
ここで より、 ですから、 と分かりました。
群の作用
ここから対称性を考える数え上げっぽい話になってきます。
突然ですが、以下のような問題を考えましょう。
もちろんこれは対称性を考えずに一度全列挙してから、重複を除く処理をして数え上げることもできます。
しかし、もっと効率的な解法が欲しいとなった場合どうすればよいでしょうか。
ここで回転と反転という操作に着目してみると
上の六つの操作が回転や反転を行う方法すべてであると分かります。
これらの操作は、実は 次の置換全体の集合 (つまり三次対称群) と同一視することができます。
なぜならば、これらの操作は ある点をほかの点へ置換する 操作と言い換えることができ、これはまさに置換の定義と同様だからです。
したがって、三角形の回転と反転による操作は、ある 次の置換 があって、 の順列 を へと置き換えるような操作へ言い換えることができます。このようにある群の要素によって集合に行う操作を、 群作用と呼びます。
より形式的な定義をします。
を に対して群、 を の単位元、 を集合とすると、関数 が以下の条件
全ての に対して、
全ての に対して、
を満たすとき、 を の への左作用と呼び、
また、関数 が以下の条件
全ての に対して、
全ての に対して、
を満たすとき、 を の への右作用と呼びます。
から への右作用もしくは左作用が存在するならば、 は に作用するといいます。
この記事ではこれ以降、断りのない限り左作用であるとし を単に と書きます。
先ほどの例では、 の順列の全体集合とすると、
を任意の に対して と定めればよいです。
群の軌道 / 安定化群と不動点集合
群 が集合 に対して作用しているとします。このとき、 に対して
を の による 軌道と呼び、
を の安定化群と呼びます。
また、 に対して
を の不動点集合と呼びます。
それぞれのお気持ちとしては、
軌道: に対して操作を繰り返したときにできるパターンの集合
安定化群: を変化させないような操作の集合
不動点集合: 操作 に対して不変であるようなパターンの集合
のような感じです。
安定化群に対して、以下の定理は基本的です。
証明
関数 を任意の に対して と定めます。 この関数が well-defined であることを確認しましょう。
が を満たすとします。この時
であるため、 は well-defined です。さらにこれらはすべて同値であることから、 が全単射であることも従います。
したがって の要素と の要素は一対一対応し、 が示せました。
群作用による同値関係
剰余類を考えたときと同じような関係を定義します。
群 が集合 に対して作用しているとしたとき、 に対して、関係 を であることと定めます。このとき関係 は同値関係です。
ここで であることの意味を考えてみると、これは対称性を考慮したとき と を同一視してもよいととらえることができます。 ここで、
と定めれば、 本質的には を求めることによって対称性を考慮した数え上げができると分かります。
バーンサイドの補題
いよいよ本題(補題ですが)です。まずは主張を確認してみましょう。
砕けた言葉で言いかえれば「対称性を考えたときの数え上げの答えは各操作に対して不変なものに対する答えの総和を操作の種類数で割ったものに等しい」となります。
これを用いて先ほどの問題を解いてみましょう。
解法
先ほど行った議論から、回転に関しては とすればよいです。
また、 とし、 を任意の に対して とすると、 は左作用です。
あとは地道に によって場合分けを行っていきましょう。
(i) のとき
このとき は なる の組の数に等しいです。
(ii) のとき
このとき任意の は であるため、 は であるとき 、そうでないとき です。
(iii) のとき
(ii) と同様に であるとき 、そうでないとき です。
(iv) のとき
このとき任意の は を満たします。 したがって は なる の組の数に等しいです。
(v) のとき
(iv) と同様に なる の組の数に等しいです。
(vi) のとき
(iv) と同様に なる の組の数に等しいです。
したがってこれらの和を取って で割ればよいです。
上のような組の数を求めるのは例えば Bostan-Mori 法で 時間になります。
よって、この問題を 時間で解けました。
使い方もわかったところでバーンサイドの補題を証明していきましょう。
証明
の式の形を見ると、 ごとに を計算するのは大変ですから、 ごとに計算したいです。
ここで は なる の集合でしたから、結局これを数えればよく
と変形したのち、軌道安定化群定理とラグランジュの定理より
であり、ここで軌道がただ一つであったことより と分かります。したがって
より、示すことができました。
証明
同値な言いかえとして を示します。
今、補題の補題をうまく使うために軌道ごとに足し合わせていくことにします。このとき
と変形すれば、補題より
参考文献
[1] 岡本 吉央 "離散数理工学 第 7 回 離散代数:対称性を考慮した数え上げ" (閲覧日: 2023-11-07) http://dopal.cs.uec.ac.jp/okamotoy/lect/2014/dme/lect07.pdf
[2] soratobipenguin "バーンサイドの補題" (閲覧日:2023-11-07) https://soratobipenguin.hatenablog.com/entry/2018/05/05/160718
Wolfram Alpha / Wolfram Script を競プロで使おう!
注意
本記事には ABC154-F および エイシングプログラミングコンテスト2020-F のネタバレが含まれます。
本題
皆さん、 Woflram Alpha を使ったことはありますか? 私はあります。
さて、Wolfram Alpha だと入力長制限や実行時間制限で計算できないことがあって若干煩わしいですよね。
そこで手元実行でそのようなことを気にせず使える Wolfram Script を導入しましょう!
そこまで難しい手順でもないので導入は公式に譲ります。 reference.wolfram.com
実際に使ってみる
ABC154-F Many Many Paths
問題概要
正整数 および が与えられるので、 を で求めてください。
解法
とりあえずそのまま式を入力してみます、すると 事前計算のもと で解ける式を教えてくれます!
これを愚直に実装して AC を得られます。
エイシングプログラミングコンテスト2020-F Two Snuke
問題概要
次の問題を 個の与えられるケースについて解いてください。
正整数 が与えられるので、 かつ を満たすようなすべての長さ の数列 について、 それぞれ を計算し、その総和を で求めてください。
解法
FPS による考察を用います。
まず立式することを考えると、これは積の和典型のような形をしていますから
と定めれば、
が求めるべき答えであることは明らかです、ここで を具体的に計算すればあとは Bostan-Mori で殴って終わりそうですので、これを Wolfram に投げつけます。
と求めてくれたので、
と分かりました、よって答えは で計算できて十分高速に動作し、 AC を得られます。
おまけ
先ほど解いた Two Snuke は 解法もあるのですが、それも Wolfram で導出できます。
今、 求めたい値は であることがわかっていて、これは に等しいですから、これを考えます。
Wolfram 言語で SeriesCoefficient[1/(1-x)^16 1/(1+x)^5,{x,0,n}]
と書くと を表せるので、これをターミナルに入力すると超長い式が返ってきます。
一旦 FullSimplify[%]
と入力することでこの式を簡約化して
Piecewise
(条件分岐用の関数) が邪魔なので InputForm[%]
を入力してキーボードで打てる一般的な形にしてから中身をコピーして
その中身も長くて扱いにくいので一度入力して %
として扱えるようにしてから、PolynomialMod[%,10^9+7]
を入力して剰余をとって
さらにもう一度 InputForm[%]
で整えて
いい感じの式を得られました。
あとは Vscode などの置換機能で (スペースと+) を %mod
などに置き換えるとコピペで使えるようになります。
実際にほぼコピペで AC したコード: atcoder.jp
ABC321 F - #(subset sum = K) with Add and Erase があの遷移でいい理由を理解する
わかっていてほしいもの
- 数 IA の多項式の四則演算
はじめに
ここでは多項式の実装等は扱わず、どうして遷移があのようになるかを取り扱います。また、わかりやすさのために厳密性を欠く記述があります。
本題
dp 配列と多項式を関連付けると嬉しい場合があります、これもそのうちの一つです。
最初からこの問題を考えると難しいので、箱から取り出すことがない場合を考えましょう。
すると、これは以下のように dp 配列を更新することで解けるはずです。
ここで、これを多項式によって書くことを考えます。
仮に、多項式の次数を に相当するもの、 の係数を の中身に相当するものとし、これをどう遷移させるかを考えます。
(具体的には という多項式です)
ここで考えていた dp は
と書き直すことができます。
一つ前の状態の和に だけ下駄をはかせたもの というのは、 一つ前の状態に を掛けたものに等しいです。
よって、次のように書けることがわかります。
この形のまま、箱から取り出すことがある場合を考えましょう。
問題文から、取り出される際に が を因数に持つことがわかります。
ここで多項式は乗法について可換ですから、 の一番右に をもってきて、 で割って打ち消してしまいましょう。
直感的に乗算と除算は逆の演算ですから、dp として扱う際も逆の操作をすればよさそうです。
したがって、取り出すときの更新は以下のように書けます
よって、この遷移を実装して、 時間でこの問題を解くことが出来ました。
(FPS を用いた提出:提出 #45905788 - サントリープログラミングコンテスト2023(AtCoder Beginner Contest 321))
(dp での提出:https://atcoder.jp/contests/abc321/submissions/45925519)
入緑記事
始めに
中三の Python 勢です 23/09/23 の ABC321 で入緑したのでやったことなどを書いておこうかと
やったこと
とりあえず精進!精進をしましょう
ちゃんと理解していて、且つ書けるアルゴリズム/データ構造はこんな感じです
- 二分探索
- 基本的な dp
- bit 全探索
- bit dp
- BFS/DFS
- UnionFind
- heapq
- Dijkstra 法
- Warshall-Floyd 法
- Rolling Hash
- Segment Tree
- BIT
- 中国式剰余定理
- FFT/NTT
上の方が実践で出くわす頻度が高いと思います
とりあえず出逢ったアルゴリズム/データ構造はバンバン記事を読むなどして理解できると良いです!
ABC276 F - Double Chance を解くときに考えたこと
はじめに
自分の思考を殴り書いているような面があるので、文章の体裁はあまり保たれていませんし、解説もそこまでわかりやすくないです。
また、厳密性を欠くような部分もあると思いますが、ご容赦ください。
問題概要
整数列 が与えられます。
について、以下のクエリに答えてください。
の部分列 から無作為に つの要素を選ぶことを二回繰り返します。(このとき、要素が重複してもよいです)
選ばれた要素のうち最大のものの期待値を有理数 で出力してください。
とっかかり
とりあえずあるに対する期待値がいくらか考えてみます。
がソートされていると嬉しいので、例えば std::multiset などに入れ、ソートされた を考えたいです。
混同を防ぐためにソートされた を と書くことにします。
最初に が選ばれたとき、それが最後まで最大である場合の数を考えてみましょう。
これは二回目で 以下の値を引けばいいですから、 を超えない最大のインデックスを として です。
逆に、二回目で が選ばれたとき、それが最大である場合の数も、 です。
よって、 が最大である場合の数は であるように思えますが、罠があります。
それは を二回選ぶような方法を重複してカウントしていることです。
よってその分を引いて場合の数は であると分かりました。
したがって求めるべき期待値は です。
これを便宜上、 と書くことにします。
計算量改善
さて、これを愚直に計算すると、全体計算量になってしまい間に合いません。(ユーザー解説にある通りコンパイル設定をいじれば通せはします)
そこで計算結果を使いまわすことを考えます。
が、ソートした結果 に入ったとして、期待値を計算しましょう。
の期待値に対する寄与を考えると、これは が求められれば良いです。
例えば std::multiset::upper_bound 等で 時間でできます。
次に、 以外の寄与を考えます。 であるとき、 であり、 のとき、です。
したがって 以外の寄与は
と計算できます。
は使いまわせますから、 を素早く計算することを考えます。
区間和なのでセグ木を使いたいな~という気持ちになります。
そこで、重複している場合にインデックスを増やす座圧を行ったうえで、全要素 で初期化した長さ のセグ木を作りそこに要素を入れていけばよいです。
こうすると が で求められました。
したがって一クエリあたりの計算量は であり、総計算量 でこの問題に答えることができました。これは十分高速に動作し、 AC を得ることができます。