For integers \(m\ge2\) and \(n\ge1\), we place \(mn\) toppings around a circle, with exactly \(n\) copies of each of the \(m\) colors. Two arrangements are considered the same if one is a rotation of the other. Let \(f(m,n)\) be the number of distinct rotational classes. The Project Euler task is to sum all values satisfying
$$f(m,n)\le 10^{15}.$$
The final numeric sum is intentionally omitted here; the goal is to explain the counting formula and the search bounds used by the C++ solution.
The acting group is the cyclic rotation group
$$C_{mn}=\{0,1,\dots,mn-1\},$$
where rotation by \(r\) means shifting every position by \(r\) places around the circle.
Burnside's lemma says that the number of rotational classes is the average number of arrangements fixed by each rotation:
$$f(m,n)=\frac{1}{mn}\sum_{r=0}^{mn-1}\mathrm{Fix}(r).$$
So the whole problem is to understand \(\mathrm{Fix}(r)\) for one rotation \(r\).
Set
$$N=mn,\qquad d=\gcd(N,r).$$
The rotation by \(r\) decomposes the \(N\) positions into
$$d$$
disjoint cycles, each of length
$$\ell=\frac{N}{d}.$$
This is the standard cycle decomposition of a cyclic shift.
An arrangement is fixed by this rotation if and only if every cycle is monochromatic: once one position in a cycle is chosen, all other positions in that cycle are forced to have the same color.
Each color appears exactly \(n\) times. If every cycle has length \(\ell\), then every color must occupy a whole number of cycles. Therefore
$$\ell \mid n$$
is necessary.
It is also sufficient. If \(\ell\mid n\), then each color must occupy exactly
$$\frac{n}{\ell}$$
cycles, because each such cycle contributes \(\ell\) positions of that color.
Since there are
$$d=\frac{N}{\ell}=\frac{mn}{\ell}$$
cycles in total, a fixed arrangement exists precisely when \(\ell\mid n\).
Assume \(\ell\mid n\). Then the \(d=\frac{mn}{\ell}\) cycles are distinguishable cycle slots, and we must color them so that each of the \(m\) colors is used exactly \(\frac{n}{\ell}\) times.
So the number of fixed arrangements is the multinomial coefficient
$$\mathrm{Fix}(\ell)=\frac{\left(\frac{mn}{\ell}\right)!}{\left(\frac{n}{\ell}!\right)^m}.$$
If \(\ell\nmid n\), then
$$\mathrm{Fix}(\ell)=0.$$
Now fix a divisor \(\ell\) of \(N\). We want the number of rotations \(r\) whose cycle length is exactly \(\ell\), that is, whose gcd with \(N\) equals \(N/\ell\).
Write
$$r=\frac{N}{\ell}k.$$
Then
$$\gcd(N,r)=\frac{N}{\ell}\gcd(\ell,k).$$
So the condition \(\gcd(N,r)=N/\ell\) is equivalent to
$$\gcd(\ell,k)=1.$$
The number of such residues \(k\) modulo \(\ell\) is exactly Euler's totient:
$$\varphi(\ell).$$
Therefore there are \(\varphi(\ell)\) rotations with cycle length \(\ell\).
Only divisors \(\ell\mid n\) contribute, so Burnside becomes
$$f(m,n)=\frac{1}{mn}\sum_{\ell\mid n}\varphi(\ell)\, \frac{(mn/\ell)!}{\bigl((n/\ell)!\bigr)^m}.$$
This is exactly the formula implemented by f_value() in the C++ solution.
Here \(m=3\), \(n=2\), so \(N=6\). The divisors of \(n\) are \(1\) and \(2\). Hence
$$f(3,2)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(2!)^3}+ \varphi(2)\frac{3!}{(1!)^3} \right].$$
Now
$$\varphi(1)=1,\qquad \varphi(2)=1,$$
so
$$f(3,2)=\frac{1}{6}\left[\frac{720}{8}+6\right] =\frac{1}{6}(90+6)=16.$$
This is one of the explicit checkpoints in the code.
With two colors and three copies of each,
$$f(2,3)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(3!)^2}+ \varphi(3)\frac{2!}{(1!)^2} \right].$$
Since \(\varphi(1)=1\) and \(\varphi(3)=2\), we get
$$f(2,3)=\frac{1}{6}(20+4)=4.$$
The brute-force checkpoint in the program confirms this value by explicit necklace enumeration.
The Burnside sum is positive-term, so just the identity rotation \(\ell=1\) already gives a lower bound:
$$f(m,n)\ge \frac{1}{mn}\frac{(mn)!}{(n!)^m}=:g(m,n).$$
For fixed \(n\), this lower bound increases with \(m\). Indeed,
$$\frac{g(m+1,n)}{g(m,n)} =\frac{m}{m+1}\cdot \frac{\prod_{k=1}^{n}(mn+k)}{n!} >1.$$
So among all \(m\ge2\), the smallest possible value occurs at \(m=2\). Therefore
$$f(m,n)\ge g(2,n)=\frac{(2n)!}{2n\,(n!)^2} =\frac{1}{2n}\binom{2n}{n}.$$
If this lower bound already exceeds \(10^{15}\), then no value with that \(n\) can contribute, for any \(m\ge2\).
This is exactly why the code computes
$$\frac{1}{2n}\binom{2n}{n}$$
in compute_n_upper_bound().
Take \(n=1\). Then we place \(m\) distinct colors once each around the circle, modulo rotation. The number of circular orders is
$$f(m,1)=(m-1)!.$$
So if
$$ (m-1)! > 10^{15}, $$
then even the smallest possible \(n\) already overshoots the limit, and this \(m\) can never contribute.
That is why compute_m_upper_bound() effectively finds the largest \(m\) with
$$ (m-1)! \le 10^{15}. $$
1) Totients. compute_totients() sieves all \(\varphi(\ell)\) values up to the maximum relevant \(n\).
2) Factorials and factorial powers. factorials_up_to() precomputes \(k!\), and precompute_fact_powers() stores \((n!)^m\). This avoids repeating huge multiplications in every Burnside term.
3) Burnside evaluator. f_value(m,n,...) loops over all divisors \(\ell\mid n\), computes the multinomial fixed-count term, multiplies by \(\varphi(\ell)\), sums, and divides by \(mn\).
4) Checkpoints. The code explicitly verifies
$$f(2,1)=1,\qquad f(2,2)=2,\qquad f(3,1)=2,\qquad f(3,2)=16,$$
and then compares the formula with brute-force necklace counting for
$$ (m,n)\in\{(2,3),(2,4),(3,2),(4,2)\}. $$
5) Final scan. After the safe upper bounds are known, the program checks every \((m,n)\) in that rectangle and adds only values \(\le10^{15}\).
For each pair \((m,n)\), the work is proportional to the number of divisors of \(n\), plus big-integer arithmetic on factorial ratios. The precomputed totients, factorials, and factorial powers greatly reduce repeated work. Memory usage is dominated by those precomputed big-integer tables.
Es gibt \(m\ge2\) Farben, und jede Farbe erscheint genau \(n\)-mal auf einem Kreis mit insgesamt \(mn\) Positionen. Zwei Anordnungen gelten als gleich, wenn sie sich nur durch Rotation unterscheiden. Sei \(f(m,n)\) die Anzahl dieser Rotationsklassen. Gesucht ist die Summe aller Werte mit
$$f(m,n)\le 10^{15}.$$
Die endgültige Euler-Zahl wird hier absichtlich nicht angegeben; wichtig ist die Herleitung der Burnside-Formel und der sicheren Suchgrenzen.
Die wirkende Gruppe ist die zyklische Rotationsgruppe
$$C_{mn}=\{0,1,\dots,mn-1\}.$$
Burnside liefert
$$f(m,n)=\frac{1}{mn}\sum_{r=0}^{mn-1}\mathrm{Fix}(r).$$
Also muss man nur noch verstehen, wie viele gültige Belegungen von einer einzelnen Rotation \(r\) festgehalten werden.
Setze
$$N=mn,\qquad d=\gcd(N,r).$$
Dann zerlegt die Rotation um \(r\) Positionen die \(N\) Plätze in
$$d$$
Zyklen, jeder von Länge
$$\ell=\frac{N}{d}.$$
Eine Anordnung bleibt genau dann invariant, wenn jeder dieser Zyklen monochrom ist.
Jede Farbe kommt genau \(n\)-mal vor. Wenn alle Zyklen Länge \(\ell\) haben, dann muss jede Farbe eine ganze Zahl solcher Zyklen belegen. Also ist
$$\ell\mid n$$
notwendig.
Es ist auch hinreichend: Dann benutzt jede Farbe genau
$$\frac{n}{\ell}$$
Zyklen, denn jeder Zyklus trägt \(\ell\) Vorkommen derselben Farbe bei.
Es gibt insgesamt
$$d=\frac{mn}{\ell}$$
unterscheidbare Zyklen. Wenn \(\ell\mid n\), dann müssen wir diese \(d\) Zyklus-Slots so einfärben, dass jede der \(m\) Farben genau \(\frac{n}{\ell}\) Slots erhält. Also
$$\mathrm{Fix}(\ell)=\frac{\left(\frac{mn}{\ell}\right)!}{\left(\frac{n}{\ell}!\right)^m}.$$
Falls \(\ell\nmid n\), gibt es keine fixierte Anordnung.
Wir zählen die Rotationen mit Zykluslänge \(\ell\). Schreibe
$$r=\frac{N}{\ell}k.$$
Dann gilt
$$\gcd(N,r)=\frac{N}{\ell}\gcd(\ell,k).$$
Die Bedingung für Zykluslänge \(\ell\) ist also äquivalent zu
$$\gcd(\ell,k)=1.$$
Davon gibt es modulo \(\ell\) genau
$$\varphi(\ell)$$
Stück. Deshalb tragen die Rotationen mit gegebener Zykluslänge \(\ell\) in Burnside insgesamt mit Gewicht \(\varphi(\ell)\) bei.
Nur Teiler \(\ell\mid n\) liefern einen Beitrag. Also wird Burnside zu
$$f(m,n)=\frac{1}{mn}\sum_{\ell\mid n}\varphi(\ell)\, \frac{(mn/\ell)!}{\bigl((n/\ell)!\bigr)^m}.$$
Genau diese Formel implementiert die Funktion f_value().
Hier sind die relevanten Teiler von \(n=2\) gleich \(1\) und \(2\). Daher
$$f(3,2)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(2!)^3}+ \varphi(2)\frac{3!}{(1!)^3} \right].$$
Mit \(\varphi(1)=\varphi(2)=1\) folgt
$$f(3,2)=\frac{1}{6}(90+6)=16.$$
Das ist ein expliziter Checkpoint des Programms.
Hier erhält man
$$f(2,3)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(3!)^2}+ \varphi(3)\frac{2!}{(1!)^2} \right] =\frac{1}{6}(20+4)=4.$$
Der Brute-Force-Teil des Codes bestätigt genau diesen Wert.
Die Burnside-Summe hat nur nichtnegative Terme. Schon der Identitätsterm \(\ell=1\) liefert also eine Untergrenze:
$$f(m,n)\ge \frac{1}{mn}\frac{(mn)!}{(n!)^m}=:g(m,n).$$
Für festes \(n\) wächst \(g(m,n)\) mit \(m\), denn
$$\frac{g(m+1,n)}{g(m,n)} =\frac{m}{m+1}\cdot\frac{\prod_{k=1}^{n}(mn+k)}{n!}>1.$$
Damit ist die kleinste mögliche Untergrenze bei \(m=2\):
$$f(m,n)\ge g(2,n)=\frac{(2n)!}{2n\,(n!)^2} =\frac{1}{2n}\binom{2n}{n}.$$
Sobald dieser Ausdruck größer als \(10^{15}\) ist, kann kein Paar mit diesem \(n\) mehr beitragen. Genau deshalb benutzt compute_n_upper_bound() die Größe
$$\frac{1}{2n}\binom{2n}{n}.$$
Setzt man \(n=1\), dann hat jede Farbe genau ein Vorkommen. Die Anzahl der Kreisordnungen bis auf Rotation ist dann einfach
$$f(m,1)=(m-1)!.$$
Ist also
$$ (m-1)! > 10^{15}, $$
dann kann dieses \(m\) nie beitragen. compute_m_upper_bound() sucht daher effektiv das größte \(m\) mit
$$ (m-1)! \le 10^{15}. $$
1) Totienten. compute_totients() siebt alle \(\varphi(\ell)\)-Werte bis zur maximal relevanten \(n\)-Schranke.
2) Fakultäten und Fakultätspotenz-Tabellen. factorials_up_to() berechnet \(k!\), und precompute_fact_powers() speichert \((n!)^m\). Dadurch werden große Produkte nicht ständig neu aufgebaut.
3) Burnside-Auswertung. f_value() iteriert über alle Teiler \(\ell\mid n\), bildet den multinomialen Fix-Term, multipliziert mit \(\varphi(\ell)\), summiert und dividiert zuletzt durch \(mn\).
4) Checkpoints. Verifiziert werden
$$f(2,1)=1,\qquad f(2,2)=2,\qquad f(3,1)=2,\qquad f(3,2)=16,$$
sowie ein Brute-Force-Vergleich für
$$ (m,n)\in\{(2,3),(2,4),(3,2),(4,2)\}. $$
5) Endgültiger Suchlauf. Nach Bestimmung der sicheren Grenzen werden alle Paare \((m,n)\) im Rechteck geprüft, und nur Werte \(\le10^{15}\) werden addiert.
Für ein Paar \((m,n)\) ist der Aufwand proportional zur Anzahl der Teiler von \(n\), plus Big-Integer-Arithmetik auf Fakultätsquotienten. Vorberechnete Totienten, Fakultäten und Fakultätspotenzen reduzieren Wiederholungsarbeit stark. Der Speicherbedarf wird im Wesentlichen von diesen Big-Integer-Tabellen bestimmt.
\(m\ge2\) farklı malzeme türü ve her türden tam \(n\) adet olmak üzere toplam \(mn\) malzeme dairesel bir pizzaya yerleştiriliyor. Sadece döndürmeyle birbirine dönüşen dizilimler aynı kabul ediliyor. \(f(m,n)\), bu döndürme eşdeğerlik sınıflarının sayısıdır. Problem,
$$f(m,n)\le 10^{15}$$
koşulunu sağlayan tüm değerleri toplamayı istiyor. Nihai Project Euler toplamı burada kasıtlı olarak verilmez; amaç, formülü ve kodun kullandığı arama sınırlarını açıklamaktır.
Etki eden grup, \(mn\) konumlu daire üzerindeki döndürme grubu
$$C_{mn}=\{0,1,\dots,mn-1\}$$
olur. Burnside der ki:
$$f(m,n)=\frac{1}{mn}\sum_{r=0}^{mn-1}\mathrm{Fix}(r).$$
Yani problem, her döndürmenin kaç geçerli yerleşimi sabit bıraktığını anlamaya indirgenir.
Şunu yazalım:
$$N=mn,\qquad d=\gcd(N,r).$$
\(r\) kadar döndürme, \(N\) pozisyonu
$$d$$
adet ayrık çevrime böler; her çevrimin uzunluğu
$$\ell=\frac{N}{d}$$
olur.
Bir dizilim bu döndürmede sabit kalacaksa, her çevrim tek renkli olmak zorundadır. Çünkü çevrimdeki bir pozisyonun rengi belirlenince, dönmeyle bağlı diğer tüm pozisyonlar da aynı renkte olmalıdır.
Her renk tam \(n\) kez görünür. Tüm çevrimlerin uzunluğu \(\ell\) ise, her renk ancak tam sayıda çevrim işgal edebilir. Dolayısıyla
$$\ell\mid n$$
gerekli bir koşuldur.
Aynı zamanda yeterlidir. Çünkü \(\ell\mid n\) ise her renk tam olarak
$$\frac{n}{\ell}$$
adet çevrim doldurur; her çevrim de o renkten \(\ell\) kopya üretir.
Toplam çevrim sayısı
$$d=\frac{mn}{\ell}$$
olduğuna göre, \(\ell\mid n\) durumunda bu \(d\) ayırt edilebilir çevrim slotunu, her renk tam \(\frac{n}{\ell}\) kez kullanılacak şekilde boyarız. Bu nedenle sabit kalan yerleşim sayısı
$$\mathrm{Fix}(\ell)=\frac{\left(\frac{mn}{\ell}\right)!}{\left(\frac{n}{\ell}!\right)^m}$$
olur. Eğer \(\ell\nmid n\) ise katkı sıfırdır.
Şimdi çevrim uzunluğu \(\ell\) olan döndürmeleri sayalım. Şöyle yazalım:
$$r=\frac{N}{\ell}k.$$
O zaman
$$\gcd(N,r)=\frac{N}{\ell}\gcd(\ell,k)$$
olur. Çevrim uzunluğunun tam \(\ell\) olması için \(\gcd(N,r)=N/\ell\) gerekir; bu da
$$\gcd(\ell,k)=1$$
demektir.
Modulo \(\ell\) içinde bunun sayısı tam olarak Euler totienti kadardır:
$$\varphi(\ell).$$
Demek ki Burnside toplamında çevrim uzunluğu \(\ell\) olan döndürmelerin ağırlığı \(\varphi(\ell)\)’dir.
Yalnızca \(\ell\mid n\) olan terimler katkı verdiğinden formül
$$f(m,n)=\frac{1}{mn}\sum_{\ell\mid n}\varphi(\ell)\, \frac{(mn/\ell)!}{\bigl((n/\ell)!\bigr)^m}$$
biçimine iner. Kodda f_value() tam olarak bunu hesaplar.
Burada \(n=2\) olduğu için bölenler \(1\) ve \(2\)’dir:
$$f(3,2)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(2!)^3}+ \varphi(2)\frac{3!}{(1!)^3} \right].$$
\(\varphi(1)=\varphi(2)=1\) olduğundan
$$f(3,2)=\frac{1}{6}(90+6)=16$$
çıkar. Bu, kodun açık checkpoint değerlerinden biridir.
Benzer şekilde
$$f(2,3)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(3!)^2}+ \varphi(3)\frac{2!}{(1!)^2} \right] =\frac{1}{6}(20+4)=4.$$
Koddaki brute-force kolye sayımı da bu değeri doğrular.
Burnside toplamındaki tüm terimler negatife gitmediği için, yalnızca özdeşlik döndürmesinin \(\ell=1\) terimini almak bile alt sınır verir:
$$f(m,n)\ge \frac{1}{mn}\frac{(mn)!}{(n!)^m}=:g(m,n).$$
Sabit \(n\) için bu alt sınır \(m\) arttıkça büyür. Gerçekten
$$\frac{g(m+1,n)}{g(m,n)} =\frac{m}{m+1}\cdot\frac{\prod_{k=1}^{n}(mn+k)}{n!}>1.$$
Öyleyse \(m\ge2\) arasında en küçük alt sınır \(m=2\)’de elde edilir:
$$f(m,n)\ge g(2,n)=\frac{(2n)!}{2n\,(n!)^2} =\frac{1}{2n}\binom{2n}{n}.$$
Eğer bu ifade bile \(10^{15}\)’i aşıyorsa, o \(n\) için hiçbir \(m\ge2\) katkı veremez. Kodun compute_n_upper_bound() içinde kullandığı sınır tam olarak budur.
\(n=1\) alalım. Bu durumda her renk yalnızca bir kez görünür. Dairesel dizilimlerin, dönmeye göre sınıf sayısı
$$f(m,1)=(m-1)!$$
olur.
Dolayısıyla
$$ (m-1)! > 10^{15} $$
olduğunda, bu \(m\) hiçbir şekilde katkı veremez. compute_m_upper_bound() bu yüzden etkin olarak
$$ (m-1)! \le 10^{15} $$
koşulunu sağlayan en büyük \(m\)’yi bulur.
1) Totient önhesabı. compute_totients(), gerekli tüm \(\varphi(\ell)\) değerlerini elekten geçirir.
2) Faktöriyeller ve kuvvet tabloları. factorials_up_to() ile \(k!\) değerleri, precompute_fact_powers() ile de \((n!)^m\) değerleri önceden hesaplanır. Böylece büyük çarpımlar sürekli yeniden kurulmaz.
3) Burnside değerlendiricisi. f_value(), \(n\)’in tüm bölenlerini dolaşır, her bölen için multinom sabit-kalma terimini üretir, \(\varphi(\ell)\) ile çarpar, toplar ve sonunda \(mn\)’ye böler.
4) Checkpoint’ler. Kod açıkça
$$f(2,1)=1,\qquad f(2,2)=2,\qquad f(3,1)=2,\qquad f(3,2)=16$$
değerlerini kontrol eder; sonra da
$$ (m,n)\in\{(2,3),(2,4),(3,2),(4,2)\} $$
için formülü brute-force kolye sayımıyla karşılaştırır.
5) Son tarama. Güvenli \(m\) ve \(n\) sınırları bulunduğunda, dikdörtgen içindeki her \((m,n)\) çifti değerlendirilir ve yalnızca \(10^{15}\)’i aşmayan terimler toplanır.
Her \((m,n)\) çifti için maliyet, \(n\)’in bölen sayısına ve büyük tamsayı faktöriyel oranı işlemlerine bağlıdır. Önceden hesaplanan totient, faktöriyel ve faktöriyel kuvvet tabloları tekrar maliyetini ciddi biçimde düşürür. Bellek kullanımı esas olarak bu büyük tamsayı tablolarında yoğunlaşır.
Con \(m\ge2\) tipos de topping y exactamente \(n\) copias de cada tipo, se colocan \(mn\) elementos alrededor de un círculo. Dos configuraciones se consideran iguales si difieren solo por una rotación. Denotamos por \(f(m,n)\) el número de clases de equivalencia. El problema pide sumar todos los valores tales que
$$f(m,n)\le 10^{15}.$$
Aquí no mostramos el total final de Project Euler; lo importante es explicar la fórmula de Burnside y las cotas seguras del recorrido.
El grupo actuante es el grupo cíclico de rotaciones
$$C_{mn}=\{0,1,\dots,mn-1\}.$$
Por el lema de Burnside,
$$f(m,n)=\frac{1}{mn}\sum_{r=0}^{mn-1}\mathrm{Fix}(r).$$
Así, todo se reduce a contar cuántas configuraciones válidas quedan fijas por una rotación dada \(r\).
Sea
$$N=mn,\qquad d=\gcd(N,r).$$
La rotación por \(r\) posiciones descompone las \(N\) plazas en
$$d$$
ciclos disjuntos, cada uno de longitud
$$\ell=\frac{N}{d}.$$
Una disposición permanece fija si y solo si cada ciclo es monocromático.
Cada color aparece exactamente \(n\) veces. Si todos los ciclos tienen longitud \(\ell\), entonces cada color debe ocupar un número entero de ciclos. Por tanto es necesario que
$$\ell\mid n.$$
Y también es suficiente: si \(\ell\mid n\), cada color ocupa exactamente
$$\frac{n}{\ell}$$
ciclos.
El número total de ciclos es
$$d=\frac{mn}{\ell}.$$
Si \(\ell\mid n\), debemos colorear esos \(d\) ciclos distinguibles de modo que cada uno de los \(m\) colores aparezca exactamente \(\frac{n}{\ell}\) veces. Por tanto
$$\mathrm{Fix}(\ell)=\frac{\left(\frac{mn}{\ell}\right)!}{\left(\frac{n}{\ell}!\right)^m}.$$
Si \(\ell\nmid n\), la contribución es cero.
Queremos contar las rotaciones cuya longitud de ciclo es exactamente \(\ell\). Escribimos
$$r=\frac{N}{\ell}k.$$
Entonces
$$\gcd(N,r)=\frac{N}{\ell}\gcd(\ell,k).$$
La condición \(\gcd(N,r)=N/\ell\) equivale a
$$\gcd(\ell,k)=1.$$
El número de tales clases módulo \(\ell\) es precisamente
$$\varphi(\ell).$$
Por eso la agrupación por divisores produce pesos \(\varphi(\ell)\).
Solo contribuyen los divisores \(\ell\mid n\), así que Burnside se reduce a
$$f(m,n)=\frac{1}{mn}\sum_{\ell\mid n}\varphi(\ell)\, \frac{(mn/\ell)!}{\bigl((n/\ell)!\bigr)^m}.$$
Ésta es exactamente la fórmula implementada en f_value().
Los divisores de \(n=2\) son \(1\) y \(2\). Luego
$$f(3,2)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(2!)^3}+ \varphi(2)\frac{3!}{(1!)^3} \right].$$
Como \(\varphi(1)=\varphi(2)=1\), obtenemos
$$f(3,2)=\frac{1}{6}(90+6)=16.$$
Éste es uno de los checkpoints explícitos del programa.
En este caso,
$$f(2,3)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(3!)^2}+ \varphi(3)\frac{2!}{(1!)^2} \right] =\frac{1}{6}(20+4)=4.$$
El contador bruto de collares del código confirma exactamente este resultado.
La suma de Burnside tiene términos no negativos. Solo el término identidad \(\ell=1\) ya da una cota inferior:
$$f(m,n)\ge \frac{1}{mn}\frac{(mn)!}{(n!)^m}=:g(m,n).$$
Para \(n\) fijo, esta cota crece con \(m\), ya que
$$\frac{g(m+1,n)}{g(m,n)} =\frac{m}{m+1}\cdot\frac{\prod_{k=1}^{n}(mn+k)}{n!}>1.$$
Por tanto, entre todos los \(m\ge2\), la cota mínima ocurre en \(m=2\):
$$f(m,n)\ge g(2,n)=\frac{(2n)!}{2n\,(n!)^2} =\frac{1}{2n}\binom{2n}{n}.$$
Si esta cantidad ya excede \(10^{15}\), entonces ningún valor con ese \(n\) puede contribuir. Ésa es la razón de compute_n_upper_bound().
Si \(n=1\), cada color aparece una sola vez. Entonces el número de ordenaciones circulares módulo rotación es
$$f(m,1)=(m-1)!.$$
De modo que si
$$ (m-1)! > 10^{15}, $$
ese \(m\) ya no puede aportar nada. Por eso compute_m_upper_bound() busca de hecho el mayor \(m\) con
$$ (m-1)! \le 10^{15}. $$
1) Totientes. compute_totients() calcula por criba todos los valores \(\varphi(\ell)\) necesarios.
2) Factoriales y potencias de factoriales. factorials_up_to() precalcula \(k!\), y precompute_fact_powers() guarda \((n!)^m\). Así se evitan multiplicaciones grandes repetidas.
3) Evaluador de Burnside. f_value() recorre todos los divisores \(\ell\mid n\), construye el término multinomial fijo, lo multiplica por \(\varphi(\ell)\), suma y divide finalmente entre \(mn\).
4) Checkpoints. El código verifica explícitamente
$$f(2,1)=1,\qquad f(2,2)=2,\qquad f(3,1)=2,\qquad f(3,2)=16,$$
y luego compara la fórmula con un recuento bruto de collares para
$$ (m,n)\in\{(2,3),(2,4),(3,2),(4,2)\}. $$
5) Recorrido final. Con las cotas seguras ya conocidas, el programa evalúa todos los pares \((m,n)\) del rectángulo y suma solo los valores \(\le10^{15}\).
Para cada par \((m,n)\), el trabajo es proporcional al número de divisores de \(n\), más aritmética con enteros grandes sobre cocientes factoriales. Los totientes, factoriales y potencias de factoriales precalculados reducen mucho el trabajo repetido. La memoria queda dominada por esas tablas de enteros grandes.
有 \(m\ge2\) 种配料,每种恰好出现 \(n\) 次,共 \(mn\) 个,按圆周排在披萨边缘。若两个排列只差一个旋转,则视为同一种。记这样的旋转等价类个数为 \(f(m,n)\)。题目要求把所有满足
$$f(m,n)\le 10^{15}$$
的值求和。这里不写最终数值答案,而是解释代码背后的 Burnside 公式和安全边界。
作用群是长度为 \(mn\) 的循环旋转群
$$C_{mn}=\{0,1,\dots,mn-1\}.$$
Burnside 引理给出
$$f(m,n)=\frac{1}{mn}\sum_{r=0}^{mn-1}\mathrm{Fix}(r).$$
所以问题变成:对每个旋转 \(r\),有多少合法排列会在该旋转下保持不变?
记
$$N=mn,\qquad d=\gcd(N,r).$$
旋转 \(r\) 会把 \(N\) 个位置分成
$$d$$
个不交循环,每个循环长度都是
$$\ell=\frac{N}{d}.$$
一个排列在该旋转下不变,当且仅当每个循环内部颜色完全相同。
每种颜色正好出现 \(n\) 次。如果所有循环长度都是 \(\ell\),那么每种颜色必须占据整数个循环。因此必须有
$$\ell\mid n.$$
这个条件同时也是充分的:如果 \(\ell\mid n\),那么每种颜色恰好占据
$$\frac{n}{\ell}$$
个循环。
循环总数为
$$d=\frac{mn}{\ell}.$$
若 \(\ell\mid n\),那么我们要给这 \(d\) 个可区分的循环槽着色,使得每一种颜色都正好使用 \(\frac{n}{\ell}\) 次。因此固定排列数就是
$$\mathrm{Fix}(\ell)=\frac{\left(\frac{mn}{\ell}\right)!}{\left(\frac{n}{\ell}!\right)^m}.$$
若 \(\ell\nmid n\),则贡献为零。
设循环长度固定为 \(\ell\)。写作
$$r=\frac{N}{\ell}k.$$
则有
$$\gcd(N,r)=\frac{N}{\ell}\gcd(\ell,k).$$
因此“循环长度恰好为 \(\ell\)”等价于
$$\gcd(\ell,k)=1.$$
模 \(\ell\) 下满足这一条件的 \(k\) 的个数恰好是欧拉函数
$$\varphi(\ell).$$
这就是 Burnside 求和里 \(\varphi(\ell)\) 权重的来源。
只有 \(\ell\mid n\) 时才有贡献,所以 Burnside 化简为
$$f(m,n)=\frac{1}{mn}\sum_{\ell\mid n}\varphi(\ell)\, \frac{(mn/\ell)!}{\bigl((n/\ell)!\bigr)^m}.$$
这正是 C++ 中 f_value() 的实现公式。
这里 \(n=2\) 的约数是 \(1\) 与 \(2\)。因此
$$f(3,2)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(2!)^3}+ \varphi(2)\frac{3!}{(1!)^3} \right].$$
由于 \(\varphi(1)=\varphi(2)=1\),得到
$$f(3,2)=\frac{1}{6}(90+6)=16.$$
这正是代码中的一个显式 checkpoint。
同理,
$$f(2,3)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(3!)^2}+ \varphi(3)\frac{2!}{(1!)^2} \right] =\frac{1}{6}(20+4)=4.$$
代码中的 brute-force 项链计数也验证了这一结果。
Burnside 求和的每一项都非负,因此只看恒等旋转对应的 \(\ell=1\) 项,就已经得到一个下界:
$$f(m,n)\ge \frac{1}{mn}\frac{(mn)!}{(n!)^m}=:g(m,n).$$
对固定的 \(n\),这个下界随着 \(m\) 增大而增大,因为
$$\frac{g(m+1,n)}{g(m,n)} =\frac{m}{m+1}\cdot\frac{\prod_{k=1}^{n}(mn+k)}{n!}>1.$$
因此在所有 \(m\ge2\) 中,最小下界出现在 \(m=2\):
$$f(m,n)\ge g(2,n)=\frac{(2n)!}{2n\,(n!)^2} =\frac{1}{2n}\binom{2n}{n}.$$
如果这个量已经大于 \(10^{15}\),那么该 \(n\) 对应的任何 \(m\ge2\) 都不可能贡献。这正是 compute_n_upper_bound() 的逻辑。
取 \(n=1\)。此时每种颜色只出现一次。圆排列模旋转的个数就是
$$f(m,1)=(m-1)!.$$
因此只要
$$ (m-1)! > 10^{15}, $$
这个 \(m\) 就不可能贡献。于是 compute_m_upper_bound() 实际上是在找满足
$$ (m-1)! \le 10^{15} $$
的最大 \(m\)。
1) 欧拉函数预处理。 compute_totients() 筛出所有需要的 \(\varphi(\ell)\)。
2) 阶乘与阶乘幂表。 factorials_up_to() 预计算 \(k!\),而 precompute_fact_powers() 保存 \((n!)^m\)。这样 Burnside 每一项都不用反复构造大整数乘积。
3) Burnside 计算器。 f_value() 枚举所有 \(\ell\mid n\),计算对应的不变排列多项式项,乘上 \(\varphi(\ell)\) 后求和,最后再除以 \(mn\)。
4) Checkpoint。 代码显式验证
$$f(2,1)=1,\qquad f(2,2)=2,\qquad f(3,1)=2,\qquad f(3,2)=16,$$
然后对
$$ (m,n)\in\{(2,3),(2,4),(3,2),(4,2)\} $$
使用 brute-force 项链枚举与公式结果逐一比对。
5) 最终扫描。 在安全上界矩形内逐对检查 \((m,n)\),仅把 \(\le10^{15}\) 的值累加到答案中。
对每个 \((m,n)\),工作量大致与 \(n\) 的约数个数成正比,再加上大整数阶乘比的运算。预处理的欧拉函数、阶乘和阶乘幂表显著降低了重复工作。空间复杂度主要由这些大整数表占据。
Есть \(m\ge2\) типов начинки, и каждый тип встречается ровно \(n\) раз, всего \(mn\) позиций по кругу. Две раскладки считаются одинаковыми, если одна получается из другой вращением. Обозначим число классов вращательной эквивалентности через \(f(m,n)\). Нужно просуммировать все значения, удовлетворяющие
$$f(m,n)\le 10^{15}.$$
Итоговая численная сумма здесь специально не приводится; цель — объяснить формулу Бёрнсайда и безопасные границы перебора.
Действующая группа — циклическая группа вращений
$$C_{mn}=\{0,1,\dots,mn-1\}.$$
По лемме Бёрнсайда,
$$f(m,n)=\frac{1}{mn}\sum_{r=0}^{mn-1}\mathrm{Fix}(r).$$
Значит, нужно понять, сколько допустимых раскладок фиксирует каждое вращение \(r\).
Обозначим
$$N=mn,\qquad d=\gcd(N,r).$$
Тогда вращение на \(r\) позиций разбивает \(N\) мест на
$$d$$
непересекающихся циклов, каждый длины
$$\ell=\frac{N}{d}.$$
Раскладка остается инвариантной тогда и только тогда, когда каждый такой цикл одноцветен.
Каждый цвет встречается ровно \(n\) раз. Если длина каждого цикла равна \(\ell\), то каждый цвет должен занимать целое число циклов. Поэтому необходимо условие
$$\ell\mid n.$$
Оно же и достаточно: если \(\ell\mid n\), то каждый цвет занимает ровно
$$\frac{n}{\ell}$$
циклов.
Число циклов равно
$$d=\frac{mn}{\ell}.$$
Если \(\ell\mid n\), нужно раскрасить эти \(d\) различимых циклических слота так, чтобы каждый из \(m\) цветов использовался ровно \(\frac{n}{\ell}\) раз. Следовательно,
$$\mathrm{Fix}(\ell)=\frac{\left(\frac{mn}{\ell}\right)!}{\left(\frac{n}{\ell}!\right)^m}.$$
Если \(\ell\nmid n\), вклад равен нулю.
Фиксируем длину цикла \(\ell\). Пишем
$$r=\frac{N}{\ell}k.$$
Тогда
$$\gcd(N,r)=\frac{N}{\ell}\gcd(\ell,k).$$
Условие «длина цикла равна ровно \(\ell\)» эквивалентно
$$\gcd(\ell,k)=1.$$
Число таких классов \(k\) по модулю \(\ell\) равно
$$\varphi(\ell).$$
Именно отсюда в формуле Бёрнсайда возникает вес \(\varphi(\ell)\).
Вклад дают только делители \(\ell\mid n\), поэтому формула принимает вид
$$f(m,n)=\frac{1}{mn}\sum_{\ell\mid n}\varphi(\ell)\, \frac{(mn/\ell)!}{\bigl((n/\ell)!\bigr)^m}.$$
Именно это вычисляет функция f_value().
Для \(n=2\) делители равны \(1\) и \(2\), поэтому
$$f(3,2)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(2!)^3}+ \varphi(2)\frac{3!}{(1!)^3} \right].$$
Так как \(\varphi(1)=\varphi(2)=1\), получаем
$$f(3,2)=\frac{1}{6}(90+6)=16.$$
Это один из явных checkpoints в программе.
Аналогично,
$$f(2,3)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(3!)^2}+ \varphi(3)\frac{2!}{(1!)^2} \right] =\frac{1}{6}(20+4)=4.$$
Brute-force-счетчик ожерелий в коде подтверждает этот результат.
Все члены суммы Бёрнсайда неотрицательны, поэтому уже один тождественный член \(\ell=1\) дает нижнюю оценку:
$$f(m,n)\ge \frac{1}{mn}\frac{(mn)!}{(n!)^m}=:g(m,n).$$
При фиксированном \(n\) эта нижняя оценка возрастает по \(m\), потому что
$$\frac{g(m+1,n)}{g(m,n)} =\frac{m}{m+1}\cdot\frac{\prod_{k=1}^{n}(mn+k)}{n!}>1.$$
Следовательно, наименьшая возможная нижняя граница при \(m\ge2\) достигается при \(m=2\):
$$f(m,n)\ge g(2,n)=\frac{(2n)!}{2n\,(n!)^2} =\frac{1}{2n}\binom{2n}{n}.$$
Если это число уже больше \(10^{15}\), то никакое \(m\ge2\) с таким \(n\) не может внести вклад. Именно поэтому compute_n_upper_bound() использует величину
$$\frac{1}{2n}\binom{2n}{n}.$$
Если взять \(n=1\), каждый цвет встречается ровно один раз. Тогда число круговых порядков с точностью до вращения равно
$$f(m,1)=(m-1)!.$$
Значит, при
$$ (m-1)! > 10^{15} $$
такое \(m\) уже не может дать вклад. Поэтому compute_m_upper_bound() фактически ищет наибольшее \(m\), для которого
$$ (m-1)! \le 10^{15}. $$
1) Функция Эйлера. compute_totients() просеивает все значения \(\varphi(\ell)\) до нужной границы.
2) Факториалы и степени факториалов. factorials_up_to() предвычисляет \(k!\), а precompute_fact_powers() хранит \((n!)^m\). Это избавляет от повторного построения больших произведений.
3) Вычислитель Burnside. f_value() перебирает все делители \(\ell\mid n\), строит соответствующий мультиномиальный вклад, умножает на \(\varphi(\ell)\), суммирует и делит на \(mn\).
4) Checkpoints. Явно проверяются значения
$$f(2,1)=1,\qquad f(2,2)=2,\qquad f(3,1)=2,\qquad f(3,2)=16,$$
а затем формула сравнивается с brute-force-перебором ожерелий для
$$ (m,n)\in\{(2,3),(2,4),(3,2),(4,2)\}. $$
5) Финальный перебор. После нахождения безопасных границ программа проверяет все пары \((m,n)\) в соответствующем прямоугольнике и суммирует только значения \(\le10^{15}\).
Для каждой пары \((m,n)\) время пропорционально числу делителей \(n\), плюс арифметика больших чисел на факториальных отношениях. Предвычисленные тотиенты, факториалы и степени факториалов существенно снижают повторяющуюся работу. Память в основном расходуется на эти большие таблицы.
لدينا \(m\ge2\) أنواع من الإضافات، وكل نوع يظهر بالضبط \(n\) مرة، أي لدينا \(mn\) موضعًا على دائرة. إذا كان ترتيبان يختلفان فقط بدوران، فإنهما يُعدّان متماثلين. نرمز بعدد فئات التكافؤ الدوراني بـ \(f(m,n)\). المطلوب هو جمع كل القيم التي تحقق
$$f(m,n)\le 10^{15}.$$
لا نعرض هنا المجموع النهائي لـ Project Euler؛ التركيز على اشتقاق صيغة Burnside وحدود البحث الآمنة التي يستعملها الكود.
المجموعة المؤثرة هي مجموعة الدورانات الدورية
$$C_{mn}=\{0,1,\dots,mn-1\}.$$
وبحسب لمّة Burnside،
$$f(m,n)=\frac{1}{mn}\sum_{r=0}^{mn-1}\mathrm{Fix}(r).$$
إذًا يكفي أن نفهم عدد الترتيبات الصحيحة التي يثبّتها دوران واحد مقداره \(r\).
لنكتب
$$N=mn,\qquad d=\gcd(N,r).$$
فإن الدوران بمقدار \(r\) يقسم المواضع \(N\) إلى
$$d$$
دورات منفصلة، وطول كل دورة هو
$$\ell=\frac{N}{d}.$$
لكي يبقى ترتيب ما ثابتًا تحت هذا الدوران، يجب أن تكون كل دورة أحادية اللون.
كل لون يظهر تمامًا \(n\) مرة. فإذا كانت كل الدورات بطول \(\ell\)، فلا بد أن يشغل كل لون عددًا صحيحًا من الدورات. لذلك الشرط الضروري هو
$$\ell\mid n.$$
وهو أيضًا شرط كافٍ: إذا كان \(\ell\mid n\)، فكل لون يشغل بالضبط
$$\frac{n}{\ell}$$
دورات.
عدد الدورات الكلي هو
$$d=\frac{mn}{\ell}.$$
وعندما يكون \(\ell\mid n\)، نلوّن هذه الدورات \(d\) المتميزة بحيث يُستخدم كل واحد من الألوان \(m\) بالضبط \(\frac{n}{\ell}\) مرة. إذًا عدد الترتيبات المثبّتة هو
$$\mathrm{Fix}(\ell)=\frac{\left(\frac{mn}{\ell}\right)!}{\left(\frac{n}{\ell}!\right)^m}.$$
أما إذا لم يكن \(\ell\mid n\)، فالمساهمة تساوي صفرًا.
لنثبت طول الدورة \(\ell\). نكتب
$$r=\frac{N}{\ell}k.$$
فنحصل على
$$\gcd(N,r)=\frac{N}{\ell}\gcd(\ell,k).$$
إذن شرط أن يكون طول الدورة مساويًا تمامًا لـ \(\ell\) يكافئ
$$\gcd(\ell,k)=1.$$
وعدد هذه البواقي \(k\) modulo \(\ell\) هو بالضبط
$$\varphi(\ell).$$
ومن هنا يأتي وزن \(\varphi(\ell)\) في صيغة Burnside.
بما أن المساهمة تأتي فقط عندما \(\ell\mid n\)، فإن الصيغة تصبح
$$f(m,n)=\frac{1}{mn}\sum_{\ell\mid n}\varphi(\ell)\, \frac{(mn/\ell)!}{\bigl((n/\ell)!\bigr)^m}.$$
وهذه هي بالضبط الصيغة التي تطبقها الدالة f_value() في الكود.
عندما \(n=2\)، تكون القواسم هي \(1\) و\(2\). لذلك
$$f(3,2)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(2!)^3}+ \varphi(2)\frac{3!}{(1!)^3} \right].$$
وبما أن \(\varphi(1)=\varphi(2)=1\)، نحصل على
$$f(3,2)=\frac{1}{6}(90+6)=16.$$
وهذا أحد الـ checkpoints الصريحة في البرنامج.
وبنفس الطريقة،
$$f(2,3)=\frac{1}{6}\left[ \varphi(1)\frac{6!}{(3!)^2}+ \varphi(3)\frac{2!}{(1!)^2} \right] =\frac{1}{6}(20+4)=4.$$
ويؤكد العدّ brute force للأطواق في الكود هذه القيمة نفسها.
كل حدود مجموع Burnside غير سالبة، ولذلك فإن حدّ الهوية فقط عند \(\ell=1\) يعطي حدًا سفليًا:
$$f(m,n)\ge \frac{1}{mn}\frac{(mn)!}{(n!)^m}=:g(m,n).$$
وعند تثبيت \(n\)، يزداد هذا الحد السفلي مع \(m\)، لأن
$$\frac{g(m+1,n)}{g(m,n)} =\frac{m}{m+1}\cdot\frac{\prod_{k=1}^{n}(mn+k)}{n!}>1.$$
إذن أصغر حد سفلي ممكن بين جميع \(m\ge2\) يتحقق عند \(m=2\):
$$f(m,n)\ge g(2,n)=\frac{(2n)!}{2n\,(n!)^2} =\frac{1}{2n}\binom{2n}{n}.$$
فإذا كانت هذه الكمية نفسها أكبر من \(10^{15}\)، فلن يكون لأي قيمة \(m\ge2\) عند ذلك \(n\) مساهمة ممكنة. ولهذا تحسب الدالة compute_n_upper_bound() المقدار
$$\frac{1}{2n}\binom{2n}{n}.$$
إذا أخذنا \(n=1\)، فإن كل لون يظهر مرة واحدة فقط. وعدد الترتيبات الدائرية modulo الدوران هو
$$f(m,1)=(m-1)!.$$
ومن ثم إذا كان
$$ (m-1)! > 10^{15}, $$
فإن هذا \(m\) لا يمكن أن يساهم أبدًا. لهذا فإن compute_m_upper_bound() تبحث فعليًا عن أكبر \(m\) يحقق
$$ (m-1)! \le 10^{15}. $$
1) دوال أويلر. تقوم compute_totients() بحساب جميع قيم \(\varphi(\ell)\) المطلوبة بطريقة الغربال.
2) العامليات وقوى العامليات. تقوم factorials_up_to() بتهيئة \(k!\)، بينما تخزن precompute_fact_powers() القيم \((n!)^m\). وبهذا نتجنب إعادة بناء المنتجات الكبيرة في كل مرة.
3) مقيّم Burnside. تمرّ f_value() على جميع القواسم \(\ell\mid n\)، وتحسب حدّ التثبيت المتعدد الحدود، وتضربه في \(\varphi(\ell)\)، ثم تجمع وتقسم على \(mn\).
4) نقاط التحقق. يتحقق البرنامج صراحة من
$$f(2,1)=1,\qquad f(2,2)=2,\qquad f(3,1)=2,\qquad f(3,2)=16,$$
ثم يقارن الصيغة مع العد brute force للأطواق في الحالات
$$ (m,n)\in\{(2,3),(2,4),(3,2),(4,2)\}. $$
5) المسح النهائي. بعد تحديد الحدود الآمنة لـ \(m\) و\(n\)، يفحص البرنامج كل زوج \((m,n)\) داخل هذا المستطيل ويجمع فقط القيم التي لا تتجاوز \(10^{15}\).
لكل زوج \((m,n)\)، يكون العمل متناسبًا مع عدد قواسم \(n\)، إضافة إلى حسابات أعداد صحيحة كبيرة على نسب العامليات. ويساهم التحضير المسبق لقيم \(\varphi\)، والعامليات، وقوى العامليات في تقليل العمل المكرر كثيرًا. أما الذاكرة فتسيطر عليها هذه الجداول الكبيرة.