Problem Summary

For the required exponent \(m=142857\), the quantity to compute is determined by the degree-5 coefficients of

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5.$$

If

$$Q(x)^m=\sum_{i\ge 0} q_i(m)x^i,$$

then the target value is

$$T(m)=\sum_{i=0}^{5} q_i(m)\binom{5}{i}.$$

The published output is the first ten digits of the base-7 expansion of \(T(142857)\). The challenge is that \(m\) is huge, so the method must avoid full polynomial expansion.

Mathematical Approach

The key observation is that only coefficients up to \(x^5\) ever matter. That allows the whole computation to happen inside a tiny truncated polynomial ring instead of on a gigantic full expansion.

Step 1: Turn the weighted sum into one coefficient extraction

Because

$$ (1+x)^5=\sum_{j=0}^{5}\binom{5}{j}x^j, $$

multiplying \(Q(x)^m\) by \((1+x)^5\) shows that the required weighted sum is exactly the coefficient of \(x^5\):

$$T(m)=[x^5]\big(Q(x)^m(1+x)^5\big).$$

This is the central reformulation. Instead of thinking about a separate post-processing step on six coefficients, we can now treat the whole problem as a single coefficient-extraction problem.

Step 2: Factor the base polynomial

The degree-5 polynomial factors cleanly:

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5=(1+x)(1+x+x^2)^2.$$

Substituting this into the previous identity gives

$$T(m)=[x^5]\big((1+x)^{m+5}(1+x+x^2)^{2m}\big).$$

This also makes the triple-product structure visible:

$$T(m)=[x^5]\big((1+x)^5\cdot(1+x)^m\cdot(1+x+x^2)^m\cdot(1+x+x^2)^m\big).$$

So the target comes from combining one linear factor and two identical trinomial factors, all under a degree-5 coefficient extraction.

Step 3: Only the first six coefficients are ever needed

Let two formal power series be equivalent modulo \(x^6\) when they agree through degree 5. Then

$$A(x)\equiv \widetilde{A}(x)\pmod{x^6},\qquad B(x)\equiv \widetilde{B}(x)\pmod{x^6}$$

implies

$$A(x)B(x)\equiv \widetilde{A}(x)\widetilde{B}(x)\pmod{x^6}.$$

That means every multiplication may discard all terms \(x^6,x^7,\dots\) immediately, because higher-degree terms can never later contribute back to the coefficient of \(x^5\). Therefore the whole computation takes place in the quotient ring

$$\mathbb{Z}[x]/(x^6).$$

In practical terms, each intermediate polynomial is represented by exactly six coefficients.

Step 4: Binary exponentiation on truncated polynomials

Write a truncated polynomial as

$$a_0+a_1x+\cdots+a_5x^5.$$

When multiplying two such polynomials, the coefficient of \(x^n\) for \(0\le n\le 5\) is the truncated convolution

$$c_n=\sum_{i+j=n} a_i b_j.$$

All terms with \(i+j>5\) are ignored. Since \(m=142857\) is large, the power \(Q(x)^m\) is computed by exponentiation by squaring: repeatedly square the current base, multiply it into the accumulator when the current binary digit of \(m\) is \(1\), and truncate after every multiplication. The number of polynomial multiplications is therefore \(O(\log m)\), not \(O(m)\).

Step 5: Equivalent coefficient formulas

The factorization also gives a closed coefficient expression. If

$$a_r(m)=[x^r](1+x+x^2)^{2m},$$

then

$$T(m)=\sum_{r=0}^{5}\binom{m+5}{5-r}a_r(m).$$

For fixed \(r\), the coefficient \(a_r(m)\) counts choices of \(r\) total degree from \(2m\) copies of \(1+x+x^2\). If exactly \(j\) factors contribute \(x^2\), then \(r-2j\) factors contribute \(x\), so

$$a_r(m)=\sum_{j=0}^{\lfloor r/2\rfloor}\binom{2m}{j}\binom{2m-j}{r-2j}.$$

This formula is mathematically useful, but the implementations do not need to evaluate it explicitly because truncated powering is simpler and already exact.

Worked Example

For \(m=1\),

$$T(1)=[x^5]\big((1+x)^6(1+x+x^2)^2\big).$$

Now

$$ (1+x+x^2)^2 = 1+2x+3x^2+2x^3+x^4, $$

and the needed coefficients of \((1+x)^6\) are

$$1,6,15,20,15,6,\dots$$

Therefore

$$T(1)=6\cdot 1+15\cdot 2+20\cdot 3+15\cdot 2+6\cdot 1=132.$$

The implementations also use a larger checkpoint at \(m=10\). Modulo \(x^6\),

$$Q(x)^{10}\equiv 1+30x+455x^2+4640x^3+35715x^4+220906x^5,$$

so

$$T(10)=1+30\cdot 5+455\cdot 10+4640\cdot 10+35715\cdot 5+220906=450582.$$

After scaling, this becomes

$$7^{10}T(10)=127278262644918,$$

which is exactly the consistency value checked by the implementation.

How the Code Works

The C++, Python, and Java implementations all follow the same structure. They store a truncated polynomial as a length-6 coefficient array, multiply two such arrays by convolution while discarding every term above degree 5, and use binary exponentiation to obtain the exact degree-5 truncation of \(Q(x)^{142857}\).

Once those six coefficients are known, the implementation forms the weighted sum with the sixth row of Pascal's triangle, namely \(1,5,10,10,5,1\). That produces the exact integer \(T(142857)\) without any floating-point approximation.

Finally, the implementation converts that integer to base 7 by repeated division and returns the first ten digits. One implementation also checks the intermediate value at exponent \(10\), confirming that the truncated arithmetic is behaving correctly before tackling the full exponent.

Complexity Analysis

Each truncated multiplication uses only coefficients of degrees \(0\) through \(5\), so it performs a constant amount of work: \(21\) coefficient products and the corresponding additions. Exponentiation by squaring needs \(O(\log m)\) such multiplications. Therefore the algorithm runs in \(O(\log m)\) big-integer operations and uses \(O(1)\) coefficient storage. The only growth comes from the size of the integers themselves, which must be large enough to hold the exact coefficients and the final base-7 conversion.

Footnotes and References

  1. Project Euler problem page: https://projecteuler.net/problem=831
  2. Generating functions: Wikipedia - Generating function
  3. Exponentiation by squaring: Wikipedia - Exponentiation by squaring
  4. Binomial theorem: Wikipedia - Binomial theorem
  5. Multinomial theorem: Wikipedia - Multinomial theorem

Problemzusammenfassung

Für den geforderten Exponenten \(m=142857\) wird eine Zielgröße aus den Koeffizienten bis Grad \(5\) des Polynoms

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5$$

gebildet. Schreibt man

$$Q(x)^m=\sum_{i\ge 0} q_i(m)x^i,$$

dann ist der gesuchte Wert

$$T(m)=\sum_{i=0}^{5} q_i(m)\binom{5}{i}.$$

Ausgegeben werden die ersten zehn Ziffern der Basis-7-Darstellung von \(T(142857)\). Da \(m\) sehr groß ist, darf man das Polynom nicht vollständig entwickeln.

Mathematischer Ansatz

Der entscheidende Punkt ist, dass nur die Koeffizienten bis \(x^5\) überhaupt Einfluss auf das Ergebnis haben. Deshalb arbeitet die gesamte Lösung mit abgeschnittenen Polynomen.

Schritt 1: Die gewichtete Summe als Koeffizientenoperator schreiben

Wegen

$$ (1+x)^5=\sum_{j=0}^{5}\binom{5}{j}x^j $$

ist die gewünschte gewichtete Summe genau der Koeffizient von \(x^5\) in einem Produkt:

$$T(m)=[x^5]\big(Q(x)^m(1+x)^5\big).$$

Damit wird aus einer Nachbearbeitung von sechs Koeffizienten ein einziges sauberes Koeffizientenproblem.

Schritt 2: Das Basispolynom faktorisieren

Das Polynom zerfällt in sehr einfache Faktoren:

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5=(1+x)(1+x+x^2)^2.$$

Folglich gilt

$$T(m)=[x^5]\big((1+x)^{m+5}(1+x+x^2)^{2m}\big).$$

Schreibt man den Ausdruck etwas anders, sieht man die Struktur des Titels unmittelbar:

$$T(m)=[x^5]\big((1+x)^5\cdot(1+x)^m\cdot(1+x+x^2)^m\cdot(1+x+x^2)^m\big).$$

Also steckt hinter der Aufgabe ein Produkt aus einem linearen Faktor und zwei identischen trinomialen Faktoren, alles unter einer Extraktion des Grades \(5\).

Schritt 3: Warum Abschneiden nach Grad 5 exakt ist

Seien zwei formale Potenzreihen modulo \(x^6\) gleich, wenn sie bis einschließlich Grad \(5\) übereinstimmen. Dann folgt aus

$$A(x)\equiv \widetilde{A}(x)\pmod{x^6},\qquad B(x)\equiv \widetilde{B}(x)\pmod{x^6}$$

sofort

$$A(x)B(x)\equiv \widetilde{A}(x)\widetilde{B}(x)\pmod{x^6}.$$

Höhere Grade können also zu keinem späteren Zeitpunkt mehr auf den Koeffizienten von \(x^5\) zurückwirken. Man darf nach jeder Multiplikation alle Terme ab \(x^6\) löschen. Die Rechnung findet damit vollständig in

$$\mathbb{Z}[x]/(x^6)$$

statt, also mit genau sechs Koeffizienten pro Zwischenstand.

Schritt 4: Binäres Potenzieren mit abgeschnittenen Polynomen

Ein abgeschnittenes Polynom hat die Form

$$a_0+a_1x+\cdots+a_5x^5.$$

Beim Produkt zweier solcher Polynome ist für \(0\le n\le 5\) der Koeffizient

$$c_n=\sum_{i+j=n} a_i b_j.$$

Alle Beiträge mit \(i+j>5\) werden verworfen. Da \(m\) groß ist, wird \(Q(x)^m\) nicht durch \(m-1\) aufeinanderfolgende Multiplikationen berechnet, sondern per Exponentiation by squaring. Dadurch sinkt die Zahl der Multiplikationen auf \(O(\log m)\).

Schritt 5: Äquivalente geschlossene Koeffizientenformel

Aus der Faktorisierung erhält man auch eine explizite Summenformel. Mit

$$a_r(m)=[x^r](1+x+x^2)^{2m}$$

folgt

$$T(m)=\sum_{r=0}^{5}\binom{m+5}{5-r}a_r(m).$$

Für festes \(r\) zählt \(a_r(m)\), wie viele der \(2m\) Faktoren den Beitrag \(x^2\), wie viele den Beitrag \(x\) und wie viele den Beitrag \(1\) liefern. Wenn genau \(j\) Faktoren \(x^2\) liefern, dann müssen \(r-2j\) Faktoren \(x\) liefern. Also

$$a_r(m)=\sum_{j=0}^{\lfloor r/2\rfloor}\binom{2m}{j}\binom{2m-j}{r-2j}.$$

Diese Formel ist mathematisch nützlich, praktisch aber nicht nötig, weil das abgeschnittene Potenzieren bereits exakt und direkt ist.

Durchgerechnetes Beispiel

Für \(m=1\) erhält man

$$T(1)=[x^5]\big((1+x)^6(1+x+x^2)^2\big).$$

Dabei ist

$$ (1+x+x^2)^2 = 1+2x+3x^2+2x^3+x^4, $$

und von \((1+x)^6\) werden nur die ersten relevanten Koeffizienten benötigt:

$$1,6,15,20,15,6,\dots$$

Somit

$$T(1)=6\cdot 1+15\cdot 2+20\cdot 3+15\cdot 2+6\cdot 1=132.$$

Die Implementierung enthält außerdem einen Kontrollwert für \(m=10\). Modulo \(x^6\) gilt

$$Q(x)^{10}\equiv 1+30x+455x^2+4640x^3+35715x^4+220906x^5,$$

daher

$$T(10)=1+30\cdot 5+455\cdot 10+4640\cdot 10+35715\cdot 5+220906=450582.$$

Nach Skalierung ergibt sich

$$7^{10}T(10)=127278262644918,$$

genau der Wert, den die Implementierung zur Konsistenzprüfung verwendet.

Wie der Code arbeitet

Die C++-, Python- und Java-Implementierungen benutzen dieselbe Struktur. Ein abgeschnittenes Polynom wird als Feld mit sechs Koeffizienten gespeichert. Die Multiplikation ist eine Faltung, bei der alle Terme oberhalb von Grad \(5\) sofort verworfen werden.

Anschließend wird das Basispolynom mit binärer Exponentiation auf die Potenz \(142857\) gebracht. Sobald diese sechs Koeffizienten feststehen, bildet die Implementierung die gewichtete Summe mit der sechsten Zeile des Pascalschen Dreiecks, also \(1,5,10,10,5,1\).

Am Ende wird die exakte Ganzzahl in Basis \(7\) umgerechnet und die ersten zehn Ziffern werden ausgegeben. Eine zusätzliche Prüfung bei Exponent \(10\) stellt sicher, dass die abgeschnittene Arithmetik korrekt arbeitet.

Komplexitätsanalyse

Eine abgeschnittene Multiplikation benötigt nur konstante Arbeit, nämlich \(21\) Koeffizientenprodukte plus die zugehörigen Additionen. Mit Exponentiation by squaring sind \(O(\log m)\) solcher Multiplikationen nötig. Insgesamt ergibt sich also \(O(\log m)\) Aufwand in Big-Integer-Operationen und \(O(1)\) Speicher für die Koeffizienten. Wachsen müssen nur die Ganzzahlen selbst, weil die exakten Koeffizienten sehr groß werden.

Fußnoten und Referenzen

  1. Project-Euler-Problemseite: https://projecteuler.net/problem=831
  2. Erzeugende Funktionen: Wikipedia - Erzeugende Funktion
  3. Exponentiation by squaring: Wikipedia - Exponentiation by squaring
  4. Binomischer Lehrsatz: Wikipedia - Binomischer Lehrsatz
  5. Multinomialsatz: Wikipedia - Multinomialtheorem

Problem Özeti

İstenen üs değeri \(m=142857\) için hedef büyüklük,

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5$$

polinomunun yalnızca derece \(5\)'e kadar olan katsayılarından üretilir. Eğer

$$Q(x)^m=\sum_{i\ge 0} q_i(m)x^i$$

ise, aranan sayı

$$T(m)=\sum_{i=0}^{5} q_i(m)\binom{5}{i}$$

olur. Yayınlanan çıktı, \(T(142857)\) değerinin 7 tabanındaki ilk on basamağıdır. Asıl zorluk, \(m\) çok büyük olduğu için polinomu tam açmadan bunu hesaplayabilmektir.

Matematiksel Yaklaşım

Temel fikir şudur: sonuca yalnızca \(x^0\) ile \(x^5\) arasındaki katsayılar etki eder. Bu yüzden bütün hesaplama, tam polinom yerine kesilmiş polinomlar üzerinde yapılabilir.

Adım 1: Ağırlıklı toplamı tek bir katsayı çekimine dönüştür

Çünkü

$$ (1+x)^5=\sum_{j=0}^{5}\binom{5}{j}x^j, $$

istenen ağırlıklı toplam doğrudan şu katsayıya eşittir:

$$T(m)=[x^5]\big(Q(x)^m(1+x)^5\big).$$

Böylece ayrı ayrı altı katsayıyı ağırlıklandırmak yerine, problemi tek bir \(x^5\) katsayısı problemine indirgemiş oluruz.

Adım 2: Taban polinomu çarpanlara ayır

Bu polinom çok düzenli biçimde ayrışır:

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5=(1+x)(1+x+x^2)^2.$$

Dolayısıyla

$$T(m)=[x^5]\big((1+x)^{m+5}(1+x+x^2)^{2m}\big)$$

elde edilir. Bunu başka bir şekilde yazarsak üçlü çarpım yapısı açıkça görülür:

$$T(m)=[x^5]\big((1+x)^5\cdot(1+x)^m\cdot(1+x+x^2)^m\cdot(1+x+x^2)^m\big).$$

Yani hedef değer, bir lineer çarpan ile iki özdeş üçterimli çarpanın birleşiminden doğan derece-\(5\) katsayısıdır.

Adım 3: Neden derece 5'te kesmek tamamen güvenlidir

İki biçimsel kuvvet serisi derece \(5\)'e kadar aynıysa, onları \(x^6\) modunda eşit kabul edelim. O zaman

$$A(x)\equiv \widetilde{A}(x)\pmod{x^6},\qquad B(x)\equiv \widetilde{B}(x)\pmod{x^6}$$

ise mutlaka

$$A(x)B(x)\equiv \widetilde{A}(x)\widetilde{B}(x)\pmod{x^6}$$

olur. Bu, \(x^6\) ve üzerindeki terimlerin daha sonra dönüp \(x^5\) katsayısını etkileyemeyeceği anlamına gelir. Dolayısıyla her çarpımdan sonra yüksek dereceleri atmak tam olarak doğrudur. Hesap aslında

$$\mathbb{Z}[x]/(x^6)$$

halka yapısında gerçekleşir ve her ara adım yalnızca altı katsayı içerir.

Adım 4: Kesilmiş polinomlarda ikili üs alma

Bir ara polinomu

$$a_0+a_1x+\cdots+a_5x^5$$

şeklinde temsil ederiz. İki böyle polinom çarpıldığında, \(0\le n\le 5\) için \(x^n\) katsayısı

$$c_n=\sum_{i+j=n} a_i b_j$$

olur. \(i+j>5\) olan tüm katkılar yok sayılır. Çok büyük üs için \(Q(x)^m\) değerini ardışık \(m-1\) çarpım ile değil, binary exponentiation ile hesaplarız. Böylece gereken çarpım sayısı \(O(m)\) yerine \(O(\log m)\) olur.

Adım 5: Eşdeğer kapalı katsayı formülü

Çarpanlara ayrılmış biçim, doğrudan bir katsayı toplamı da verir. Eğer

$$a_r(m)=[x^r](1+x+x^2)^{2m}$$

ise,

$$T(m)=\sum_{r=0}^{5}\binom{m+5}{5-r}a_r(m)$$

olur. Burada \(a_r(m)\), \(2m\) tane \((1+x+x^2)\) çarpanından toplam derece \(r\) oluşturmanın sayısını verir. Tam olarak \(j\) tanesi \(x^2\) katkısı yaparsa, geri kalan dereceyi üretmek için \(r-2j\) tanesi \(x\) vermelidir. Bu yüzden

$$a_r(m)=\sum_{j=0}^{\lfloor r/2\rfloor}\binom{2m}{j}\binom{2m-j}{r-2j}$$

elde edilir. Bu formül doğru olsa da uygulama onu açıkça hesaplamaz; kesilmiş üs alma zaten aynı sonucu daha doğrudan verir.

Çözümlü Örnek

\(m=1\) için

$$T(1)=[x^5]\big((1+x)^6(1+x+x^2)^2\big)$$

olur. Ayrıca

$$ (1+x+x^2)^2 = 1+2x+3x^2+2x^3+x^4 $$

ve \((1+x)^6\)'nın gereken katsayıları

$$1,6,15,20,15,6,\dots$$

şeklindedir. Dolayısıyla

$$T(1)=6\cdot 1+15\cdot 2+20\cdot 3+15\cdot 2+6\cdot 1=132.$$

Uygulama ayrıca \(m=10\) için bir kontrol noktası kullanır. \(x^6\) modunda

$$Q(x)^{10}\equiv 1+30x+455x^2+4640x^3+35715x^4+220906x^5$$

olduğu için

$$T(10)=1+30\cdot 5+455\cdot 10+4640\cdot 10+35715\cdot 5+220906=450582$$

elde edilir. Ölçekli kontrol değeri ise

$$7^{10}T(10)=127278262644918$$

olup uygulamadaki doğrulamayla tam olarak aynıdır.

Kod Nasıl Çalışır

C++, Python ve Java implementasyonları aynı şemayı izler. Her ara polinom, uzunluğu \(6\) olan bir katsayı dizisi olarak tutulur. İki dizi çarpılırken evrişim yapılır ve derece \(5\)'in üzerindeki tüm terimler anında atılır.

Daha sonra taban polinom, ikili üs alma yöntemiyle \(142857\). kuvvete yükseltilir ve böylece \(Q(x)^{142857}\) ifadesinin derece-\(5\) kesiti tam olarak elde edilir. Bu altı katsayı üzerinden Pascal üçgeninin altıncı satırı \(1,5,10,10,5,1\) ile ağırlıklı toplam alınır.

Son aşamada tam sayı 7 tabanına çevrilir ve ilk on basamak yazdırılır. Ayrıca daha küçük bir üs için yapılan kontrol, büyük üssü hesaplamadan önce aritmetiğin doğru kurulduğunu garanti eder.

Karmaşıklık Analizi

Bir kesilmiş polinom çarpımı sabit miktarda iş yapar: toplam \(21\) katsayı çarpımı ve ilgili toplama işlemleri. Binary exponentiation yüzünden gereken çarpım sayısı \(O(\log m)\) olur. Böylece toplam zaman maliyeti \(O(\log m)\) büyük tamsayı işlemi, bellek maliyeti ise katsayı sayısı açısından \(O(1)\)'dir. Büyüyen tek şey, tam katsayıları ve sonucun 7 tabanındaki gösterimini taşıyan sayıların kendisidir.

Dipnotlar ve Referanslar

  1. Project Euler problem sayfası: https://projecteuler.net/problem=831
  2. Üreteç fonksiyonlar: Wikipedia - Üreteç fonksiyon
  3. Exponentiation by squaring: Wikipedia - Exponentiation by squaring
  4. Binom teoremi: Wikipedia - Binom açılımı
  5. Çokterimli teorem: Wikipedia - Multinomial theorem

Resumen del Problema

Para el exponente requerido \(m=142857\), la cantidad buscada se construye a partir de los coeficientes hasta grado \(5\) del polinomio

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5.$$

Si escribimos

$$Q(x)^m=\sum_{i\ge 0} q_i(m)x^i,$$

entonces el valor objetivo es

$$T(m)=\sum_{i=0}^{5} q_i(m)\binom{5}{i}.$$

Lo que se publica es las primeras diez cifras de la expansión en base \(7\) de \(T(142857)\). Como \(m\) es enorme, el método debe evitar expandir el polinomio completo.

Enfoque Matemático

La observación decisiva es que sólo importan los coeficientes de \(x^0\) a \(x^5\). Por eso toda la solución trabaja con polinomios truncados en lugar de manejar la expansión completa.

Paso 1: Convertir la suma ponderada en una extracción de coeficiente

Como

$$ (1+x)^5=\sum_{j=0}^{5}\binom{5}{j}x^j, $$

la suma ponderada pedida coincide exactamente con el coeficiente de \(x^5\) en un producto:

$$T(m)=[x^5]\big(Q(x)^m(1+x)^5\big).$$

Esta reescritura es fundamental, porque reduce todo el problema a una sola extracción de coeficiente.

Paso 2: Factorizar el polinomio base

El polinomio tiene una factorización muy limpia:

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5=(1+x)(1+x+x^2)^2.$$

Entonces

$$T(m)=[x^5]\big((1+x)^{m+5}(1+x+x^2)^{2m}\big).$$

Si se separa de otra manera, aparece claramente la estructura de producto triple:

$$T(m)=[x^5]\big((1+x)^5\cdot(1+x)^m\cdot(1+x+x^2)^m\cdot(1+x+x^2)^m\big).$$

Es decir, el valor buscado proviene de un factor lineal y dos factores trinomiales idénticos, todo ello bajo una extracción del término de grado \(5\).

Paso 3: Por qué truncar en grado 5 es exacto

Si dos series formales coinciden hasta grado \(5\), las consideramos iguales módulo \(x^6\). Entonces, a partir de

$$A(x)\equiv \widetilde{A}(x)\pmod{x^6},\qquad B(x)\equiv \widetilde{B}(x)\pmod{x^6}$$

se obtiene

$$A(x)B(x)\equiv \widetilde{A}(x)\widetilde{B}(x)\pmod{x^6}.$$

Eso significa que cualquier término de grado \(6\) o superior puede eliminarse inmediatamente, porque nunca volverá a contribuir al coeficiente de \(x^5\). Toda la aritmética sucede en

$$\mathbb{Z}[x]/(x^6),$$

de modo que cada estado intermedio tiene exactamente seis coeficientes.

Paso 4: Exponenciación binaria con polinomios truncados

Un polinomio truncado se representa como

$$a_0+a_1x+\cdots+a_5x^5.$$

Al multiplicar dos polinomios de este tipo, el coeficiente de \(x^n\) para \(0\le n\le 5\) es

$$c_n=\sum_{i+j=n} a_i b_j.$$

Todos los términos con \(i+j>5\) se descartan. Para elevar \(Q(x)\) a una potencia tan grande, la implementación usa exponenciación por cuadrados sucesivos. Así, el número de multiplicaciones baja de \(O(m)\) a \(O(\log m)\).

Paso 5: Fórmula cerrada equivalente para los coeficientes

La factorización también da una suma explícita. Si definimos

$$a_r(m)=[x^r](1+x+x^2)^{2m},$$

entonces

$$T(m)=\sum_{r=0}^{5}\binom{m+5}{5-r}a_r(m).$$

Para un \(r\) fijo, \(a_r(m)\) cuenta de cuántas formas los \(2m\) factores del trinomio aportan grado total \(r\). Si exactamente \(j\) factores contribuyen con \(x^2\), entonces \(r-2j\) factores deben contribuir con \(x\). Por tanto,

$$a_r(m)=\sum_{j=0}^{\lfloor r/2\rfloor}\binom{2m}{j}\binom{2m-j}{r-2j}.$$

La implementación no evalúa esta fórmula de manera directa, porque la potenciación truncada ya produce exactamente los mismos coeficientes con menos trabajo conceptual.

Ejemplo Trabajado

Para \(m=1\),

$$T(1)=[x^5]\big((1+x)^6(1+x+x^2)^2\big).$$

Además,

$$ (1+x+x^2)^2 = 1+2x+3x^2+2x^3+x^4, $$

y los coeficientes relevantes de \((1+x)^6\) son

$$1,6,15,20,15,6,\dots$$

De ahí se obtiene

$$T(1)=6\cdot 1+15\cdot 2+20\cdot 3+15\cdot 2+6\cdot 1=132.$$

Las implementaciones también usan un punto de control en \(m=10\). Módulo \(x^6\),

$$Q(x)^{10}\equiv 1+30x+455x^2+4640x^3+35715x^4+220906x^5,$$

así que

$$T(10)=1+30\cdot 5+455\cdot 10+4640\cdot 10+35715\cdot 5+220906=450582.$$

Después de escalar, se obtiene

$$7^{10}T(10)=127278262644918,$$

que coincide exactamente con la comprobación interna de la implementación.

Cómo Funciona el Código

Las implementaciones en C++, Python y Java siguen la misma idea. Representan cada polinomio truncado como un arreglo de seis coeficientes, multiplican dos arreglos por convolución y eliminan de inmediato todo término de grado superior a \(5\).

Luego elevan el polinomio base a la potencia \(142857\) usando exponenciación binaria. Una vez obtenidos los seis coeficientes correctos, forman la suma ponderada con la sexta fila del triángulo de Pascal: \(1,5,10,10,5,1\).

Al final convierten el entero exacto a base \(7\) mediante divisiones sucesivas y devuelven las primeras diez cifras. Una comprobación adicional en el caso \(m=10\) sirve para verificar que la aritmética truncada está implementada correctamente.

Análisis de Complejidad

Cada multiplicación truncada realiza una cantidad constante de trabajo: \(21\) productos de coeficientes y sus sumas correspondientes. La exponenciación por cuadrados necesita \(O(\log m)\) multiplicaciones, de modo que el coste total es \(O(\log m)\) operaciones con enteros grandes y \(O(1)\) almacenamiento de coeficientes. Lo único que crece de verdad es el tamaño de los enteros exactos que deben mantenerse durante el cálculo y en la conversión final a base \(7\).

Notas y Referencias

  1. Página del problema: https://projecteuler.net/problem=831
  2. Funciones generadoras: Wikipedia - Función generadora
  3. Exponentiation by squaring: Wikipedia - Exponentiation by squaring
  4. Teorema del binomio: Wikipedia - Teorema del binomio
  5. Teorema multinomial: Wikipedia - Teorema multinomial

问题概述

对目标指数 \(m=142857\),需要计算的量只依赖于下面这个多项式在 \(5\) 次及以下的系数:

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5.$$

若写成

$$Q(x)^m=\sum_{i\ge 0} q_i(m)x^i,$$

那么目标值就是

$$T(m)=\sum_{i=0}^{5} q_i(m)\binom{5}{i}.$$

最终要求输出的是 \(T(142857)\) 的七进制表示的前十位。由于 \(m\) 极大,显然不能真的把 \(Q(x)^m\) 完整展开,所以必须只保留真正会影响结果的低次部分。

数学方法

整个方法的核心在于:最后只需要 \(x^0\) 到 \(x^5\) 的六个系数。于是我们可以把问题放到一个“截断后的多项式环”里来做,而不必处理完整高次项。

步骤 1:把加权求和改写成单个系数提取

由于

$$ (1+x)^5=\sum_{j=0}^{5}\binom{5}{j}x^j, $$

所以原来的加权和正好等于乘积中 \(x^5\) 的系数:

$$T(m)=[x^5]\big(Q(x)^m(1+x)^5\big).$$

这一步非常重要,因为它把“先算六个系数,再乘以二项式系数求和”的过程,统一成了一个标准的生成函数系数提取问题。

步骤 2:分解基础多项式并看出三重乘积结构

这个五次多项式可以整齐地分解为

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5=(1+x)(1+x+x^2)^2.$$

因此

$$T(m)=[x^5]\big((1+x)^{m+5}(1+x+x^2)^{2m}\big).$$

如果把它写成更接近题目标题的样子,就是

$$T(m)=[x^5]\big((1+x)^5\cdot(1+x)^m\cdot(1+x+x^2)^m\cdot(1+x+x^2)^m\big).$$

也就是说,目标量来自一个线性因子和两个完全相同的三项式因子的组合,再从这个组合里取出五次项系数。这就是“Triple Product”在代数层面的具体体现。

步骤 3:为什么每一步都只保留到 \(x^5\) 仍然完全正确

把两个形式幂级数在模 \(x^6\) 下看作相等,意思就是它们在 \(x^0\) 到 \(x^5\) 的系数全部相同。若

$$A(x)\equiv \widetilde{A}(x)\pmod{x^6},\qquad B(x)\equiv \widetilde{B}(x)\pmod{x^6},$$

那么一定有

$$A(x)B(x)\equiv \widetilde{A}(x)\widetilde{B}(x)\pmod{x^6}.$$

这意味着一旦某项的次数已经至少是 \(6\),它以后无论再乘上什么非负次数多项式,都不可能重新影响 \(x^5\) 的系数。因此,在每次乘法之后立刻丢弃所有 \(x^6,x^7,\dots\) 项,不会损失任何与答案相关的信息。

从代数上说,整个算法都在

$$\mathbb{Z}[x]/(x^6)$$

中进行。于是每个中间结果都只需要记录六个整数系数。

步骤 4:在截断多项式环中使用快速幂

把任意中间结果写成

$$a_0+a_1x+\cdots+a_5x^5.$$

若两个这样的多项式相乘,那么对每个 \(0\le n\le 5\),新多项式中 \(x^n\) 的系数就是截断卷积

$$c_n=\sum_{i+j=n} a_i b_j.$$

所有 \(i+j>5\) 的项直接忽略。这样一次乘法只涉及固定数量的系数运算。

接下来用二进制快速幂计算 \(Q(x)^m\):不断平方法底数,遇到指数的当前二进制位为 \(1\) 时就乘到累计结果里。因为指数每次都右移一位,所以总乘法次数是 \(O(\log m)\),而不是 \(O(m)\)。

步骤 5:由分解得到的等价显式公式

如果定义

$$a_r(m)=[x^r](1+x+x^2)^{2m},$$

那么根据卷积公式可得

$$T(m)=\sum_{r=0}^{5}\binom{m+5}{5-r}a_r(m).$$

这里的 \(a_r(m)\) 可以用组合计数来写成显式和式。对 \(2m\) 个因子 \((1+x+x^2)\) 而言,若恰好有 \(j\) 个因子贡献 \(x^2\),那么还需要 \(r-2j\) 个因子贡献 \(x\),其余因子贡献 \(1\)。所以

$$a_r(m)=\sum_{j=0}^{\lfloor r/2\rfloor}\binom{2m}{j}\binom{2m-j}{r-2j}.$$

这个公式很好地解释了系数的组合意义,但实现中并不需要逐项代入它,因为截断快速幂已经可以直接、准确地得到同样的六个低次系数。

计算示例

先看 \(m=1\) 的情形:

$$T(1)=[x^5]\big((1+x)^6(1+x+x^2)^2\big).$$

其中

$$ (1+x+x^2)^2 = 1+2x+3x^2+2x^3+x^4, $$

而 \((1+x)^6\) 的前几个系数是

$$1,6,15,20,15,6,\dots$$

因此五次项系数等于

$$T(1)=6\cdot 1+15\cdot 2+20\cdot 3+15\cdot 2+6\cdot 1=132.$$

实现里还使用了一个更大的校验点 \(m=10\)。在模 \(x^6\) 的意义下,

$$Q(x)^{10}\equiv 1+30x+455x^2+4640x^3+35715x^4+220906x^5,$$

于是

$$T(10)=1+30\cdot 5+455\cdot 10+4640\cdot 10+35715\cdot 5+220906=450582.$$

再乘上 \(7^{10}\) 得到

$$7^{10}T(10)=127278262644918,$$

这正是实现中用于确认计算无误的检查值。

代码如何工作

C++、Python 和 Java 实现采用的是同一套流程。它们都把一个截断多项式表示为长度为 \(6\) 的系数数组,做乘法时使用卷积公式,并且立刻丢弃所有次数大于 \(5\) 的项。

然后,它们用快速幂计算出 \(Q(x)^{142857}\) 在模 \(x^6\) 下的精确结果。拿到这六个系数后,再与帕斯卡三角形第六行 \(1,5,10,10,5,1\) 做加权求和,得到精确整数 \(T(142857)\)。

最后一步是把这个大整数反复除以 \(7\),从而转换成七进制表示,并取前十位输出。另有一个针对 \(m=10\) 的数值校验,用来确认截断多项式运算在大指数计算之前就是正确的。

复杂度分析

由于只保留六个系数,一次截断乘法的工作量是常数级,具体来说共有 \(21\) 个系数乘积以及对应的加法。快速幂需要 \(O(\log m)\) 次这样的乘法,所以总时间复杂度是 \(O(\log m)\) 次大整数运算,系数存储空间是 \(O(1)\)。真正会增长的是大整数本身的位数,因为中间系数和最终结果都需要精确保存。

注释与参考资料

  1. Project Euler 题目页面: https://projecteuler.net/problem=831
  2. 生成函数: Wikipedia - 生成函数
  3. 快速幂: Wikipedia - 平方求幂
  4. 二项式定理: Wikipedia - 二项式定理
  5. 多项式定理: Wikipedia - 多项式定理

Краткое содержание задачи

Для требуемого показателя \(m=142857\) нужная величина определяется только коэффициентами до степени \(5\) у полинома

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5.$$

Если записать

$$Q(x)^m=\sum_{i\ge 0} q_i(m)x^i,$$

то искомое число равно

$$T(m)=\sum_{i=0}^{5} q_i(m)\binom{5}{i}.$$

Нужно вывести первые десять цифр числа \(T(142857)\) в системе счисления по основанию \(7\). Поскольку показатель огромен, полное раскрытие \(Q(x)^m\) недопустимо, и требуется работать только с низкими степенями.

Математический подход

Главная идея состоит в том, что на ответ влияют только коэффициенты при \(x^0,\dots,x^5\). Поэтому можно полностью перенести вычисление в усечённое кольцо многочленов.

Шаг 1: Превратить взвешенную сумму в извлечение коэффициента

Так как

$$ (1+x)^5=\sum_{j=0}^{5}\binom{5}{j}x^j, $$

то требуемая взвешенная сумма есть просто коэффициент при \(x^5\):

$$T(m)=[x^5]\big(Q(x)^m(1+x)^5\big).$$

Это удобная переформулировка: вместо отдельной обработки шести коэффициентов задача становится одной задачей на извлечение коэффициента из производящей функции.

Шаг 2: Разложить базовый полином на множители

Полином факторизуется очень просто:

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5=(1+x)(1+x+x^2)^2.$$

Следовательно,

$$T(m)=[x^5]\big((1+x)^{m+5}(1+x+x^2)^{2m}\big).$$

Если переписать это произведение подробнее, видно и обещанную тройную структуру:

$$T(m)=[x^5]\big((1+x)^5\cdot(1+x)^m\cdot(1+x+x^2)^m\cdot(1+x+x^2)^m\big).$$

То есть задача сводится к тому, чтобы взять коэффициент степени \(5\) из произведения одного линейного и двух одинаковых трёхчленных факторов.

Шаг 3: Почему усечение до степени 5 не теряет информации

Если две формальные степенные серии совпадают до степени \(5\), будем считать их равными по модулю \(x^6\). Тогда из

$$A(x)\equiv \widetilde{A}(x)\pmod{x^6},\qquad B(x)\equiv \widetilde{B}(x)\pmod{x^6}$$

следует

$$A(x)B(x)\equiv \widetilde{A}(x)\widetilde{B}(x)\pmod{x^6}.$$

Значит, любые члены степени \(6\) и выше можно удалять сразу после каждой операции: они уже никогда не смогут повлиять на коэффициент при \(x^5\). Вся арифметика идёт в кольце

$$\mathbb{Z}[x]/(x^6),$$

и каждый промежуточный результат хранит только шесть коэффициентов.

Шаг 4: Быстрое возведение в степень в усечённом кольце

Промежуточный многочлен имеет вид

$$a_0+a_1x+\cdots+a_5x^5.$$

При умножении двух таких многочленов коэффициент при \(x^n\), где \(0\le n\le 5\), равен

$$c_n=\sum_{i+j=n} a_i b_j.$$

Все слагаемые с \(i+j>5\) отбрасываются. Чтобы вычислить \(Q(x)^m\) при очень большом \(m\), используется бинарное возведение в степень: основание многократно возводится в квадрат, а в накопитель умножается только тогда, когда текущий двоичный бит показателя равен \(1\). Это даёт \(O(\log m)\) умножений вместо \(O(m)\).

Шаг 5: Эквивалентная явная формула для коэффициентов

Из факторизации получается и полезная закрытая формула. Если определить

$$a_r(m)=[x^r](1+x+x^2)^{2m},$$

то

$$T(m)=\sum_{r=0}^{5}\binom{m+5}{5-r}a_r(m).$$

Коэффициент \(a_r(m)\) можно интерпретировать комбинаторно. Если ровно \(j\) из \(2m\) множителей дают вклад \(x^2\), то ещё \(r-2j\) множителей должны дать вклад \(x\), а остальные дают \(1\). Поэтому

$$a_r(m)=\sum_{j=0}^{\lfloor r/2\rfloor}\binom{2m}{j}\binom{2m-j}{r-2j}.$$

Эта формула полезна для понимания, но в реализации не вычисляется напрямую, потому что усечённое возведение в степень и так даёт точный результат.

Разобранный пример

Для \(m=1\) получаем

$$T(1)=[x^5]\big((1+x)^6(1+x+x^2)^2\big).$$

Причём

$$ (1+x+x^2)^2 = 1+2x+3x^2+2x^3+x^4, $$

а нужные коэффициенты у \((1+x)^6\) равны

$$1,6,15,20,15,6,\dots$$

Следовательно,

$$T(1)=6\cdot 1+15\cdot 2+20\cdot 3+15\cdot 2+6\cdot 1=132.$$

В реализации есть и более крупная контрольная точка при \(m=10\). По модулю \(x^6\)

$$Q(x)^{10}\equiv 1+30x+455x^2+4640x^3+35715x^4+220906x^5,$$

поэтому

$$T(10)=1+30\cdot 5+455\cdot 10+4640\cdot 10+35715\cdot 5+220906=450582.$$

После масштабирования получаем

$$7^{10}T(10)=127278262644918,$$

и именно это значение используется как внутренняя проверка корректности.

Как работает код

Реализации на C++, Python и Java устроены одинаково. Усечённый многочлен хранится как массив из шести коэффициентов. Умножение выполняется свёрткой, причём все члены степени выше \(5\) немедленно отбрасываются.

Далее базовый полином возводится в степень \(142857\) методом быстрого возведения в степень. После этого берутся найденные шесть коэффициентов и образуется взвешенная сумма с шестой строкой треугольника Паскаля: \(1,5,10,10,5,1\).

Затем точное большое целое переводится в основание \(7\) последовательными делениями, и выводятся первые десять цифр. Дополнительная проверка при \(m=10\) подтверждает, что вся усечённая арифметика настроена верно.

Анализ сложности

Одно усечённое умножение требует постоянного числа операций: \(21\) произведение коэффициентов и соответствующие сложения. Быстрое возведение в степень использует \(O(\log m)\) таких умножений. Значит, общий алгоритм работает за \(O(\log m)\) операций с большими целыми и требует \(O(1)\) памяти на хранение коэффициентов. Растёт только разрядность самих чисел, поскольку все коэффициенты и итоговое значение вычисляются точно.

Примечания и ссылки

  1. Страница задачи Project Euler: https://projecteuler.net/problem=831
  2. Производящая функция: Wikipedia - Производящая функция
  3. Exponentiation by squaring: Wikipedia - Exponentiation by squaring
  4. Бином Ньютона: Wikipedia - Бином Ньютона
  5. Мультиномиальная теорема: Wikipedia - Мультиномиальная теорема

ملخص المسألة

لأجل الأس المطلوب \(m=142857\)، فإن الكمية المراد حسابها تعتمد فقط على معاملات كثير الحدود حتى الدرجة \(5\) في

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5.$$

إذا كتبنا

$$Q(x)^m=\sum_{i\ge 0} q_i(m)x^i,$$

فإن القيمة الهدف هي

$$T(m)=\sum_{i=0}^{5} q_i(m)\binom{5}{i}.$$

والمطلوب في النهاية هو أول عشرة أرقام من تمثيل \(T(142857)\) في الأساس \(7\). وبما أن \(m\) كبير جدًا، فلا يمكن توسيع \(Q(x)^m\) بالكامل، بل يجب الاكتفاء بالجزء المنخفض الدرجة الذي يؤثر فعلًا في الجواب.

المنهج الرياضي

الفكرة الأساسية هي أن الجواب لا يحتاج إلا إلى معاملات \(x^0\) حتى \(x^5\). لذلك يمكن تنفيذ الحساب كله داخل حلقة كثيرات حدود مقتطعة بدل التعامل مع التوسيع الكامل ذي الدرجات العالية.

الخطوة 1: تحويل المجموع الموزون إلى استخراج معامل واحد

بما أن

$$ (1+x)^5=\sum_{j=0}^{5}\binom{5}{j}x^j, $$

فإن المجموع الموزون المطلوب يساوي تمامًا معامل \(x^5\) في حاصل الضرب

$$T(m)=[x^5]\big(Q(x)^m(1+x)^5\big).$$

هذه إعادة صياغة مهمة جدًا، لأنها تحول المسألة من “حساب ستة معاملات ثم جمعها بأوزان ثنائية” إلى مسألة معيارية واحدة في الدوال المولدة.

الخطوة 2: تحليل كثير الحدود الأساسي وإظهار بنية الضرب الثلاثي

هذا كثير الحدود يتحلل بشكل بسيط:

$$Q(x)=1+3x+5x^2+5x^3+3x^4+x^5=(1+x)(1+x+x^2)^2.$$

وعليه نحصل على

$$T(m)=[x^5]\big((1+x)^{m+5}(1+x+x^2)^{2m}\big).$$

وإذا أعدنا كتابته بطريقة أخرى ظهرت البنية الثلاثية بوضوح:

$$T(m)=[x^5]\big((1+x)^5\cdot(1+x)^m\cdot(1+x+x^2)^m\cdot(1+x+x^2)^m\big).$$

أي أن القيمة المطلوبة تأتي من عامل خطي واحد مع عاملين ثلاثيي الحدود متماثلين، ثم نأخذ من الناتج معامل الدرجة الخامسة.

الخطوة 3: لماذا يكون الاقتصار على الدرجة 5 صحيحًا تمامًا

إذا اعتبرنا سلسلتين شكليتين متساويتين بترديد \(x^6\) عندما تتطابق معاملاتهما حتى الدرجة \(5\)، فإن

$$A(x)\equiv \widetilde{A}(x)\pmod{x^6},\qquad B(x)\equiv \widetilde{B}(x)\pmod{x^6}$$

يؤدي إلى

$$A(x)B(x)\equiv \widetilde{A}(x)\widetilde{B}(x)\pmod{x^6}.$$

ومعنى ذلك أن أي حد من الدرجة \(6\) أو أعلى لا يمكنه لاحقًا أن يعود ليؤثر في معامل \(x^5\). لذلك يمكن حذف جميع الحدود العليا مباشرة بعد كل عملية ضرب من دون أي خسارة معلومات مرتبطة بالجواب.

بصياغة جبرية، يتم كل الحساب داخل

$$\mathbb{Z}[x]/(x^6),$$

ولذلك يكفي الاحتفاظ بستة معاملات فقط في كل خطوة.

الخطوة 4: استخدام الرفع السريع للأس على كثيرات الحدود المقتطعة

يمثل كل كثير حدود وسيط على الصورة

$$a_0+a_1x+\cdots+a_5x^5.$$

وعند ضرب كثيري حدود من هذا النوع، فإن معامل \(x^n\) حيث \(0\le n\le 5\) يساوي التفافًا مقتطعًا:

$$c_n=\sum_{i+j=n} a_i b_j.$$

أما جميع الحدود التي تحقق \(i+j>5\) فتُهمَل. وبما أن \(m\) كبير، فإن حساب \(Q(x)^m\) يتم بطريقة الرفع الثنائي للأس: نربع الأساس مرارًا، ونضرب في الناتج التراكمي فقط عندما تكون الخانة الثنائية الحالية للأس مساوية لـ \(1\). وهكذا يصبح عدد الضربات \(O(\log m)\) بدلًا من \(O(m)\).

الخطوة 5: صيغة مكافئة صريحة للمعاملات

يعطي التحليل أيضًا صيغة مغلقة مفيدة. إذا عرفنا

$$a_r(m)=[x^r](1+x+x^2)^{2m},$$

فإن

$$T(m)=\sum_{r=0}^{5}\binom{m+5}{5-r}a_r(m).$$

ولكل \(r\) ثابت، يمكن تفسير \(a_r(m)\) توافقيًا. فإذا ساهمت بالضبط \(j\) من بين \(2m\) العوامل بالحد \(x^2\)، فيجب أن تساهم \(r-2j\) عوامل أخرى بالحد \(x\)، بينما تساهم بقية العوامل بالعدد \(1\). لذلك

$$a_r(m)=\sum_{j=0}^{\lfloor r/2\rfloor}\binom{2m}{j}\binom{2m-j}{r-2j}.$$

هذه الصيغة توضّح المعنى الرياضي للمعاملات، لكن التنفيذ لا يحتاج إلى حسابها حرفيًا، لأن الرفع السريع مع الاقتطاع يعطي المعاملات الستة المطلوبة مباشرة وبصورة دقيقة.

مثال محلول

عندما \(m=1\)، نحصل على

$$T(1)=[x^5]\big((1+x)^6(1+x+x^2)^2\big).$$

كما أن

$$ (1+x+x^2)^2 = 1+2x+3x^2+2x^3+x^4, $$

ومعاملات \((1+x)^6\) التي نحتاجها هي

$$1,6,15,20,15,6,\dots$$

ومن ثم

$$T(1)=6\cdot 1+15\cdot 2+20\cdot 3+15\cdot 2+6\cdot 1=132.$$

وتستخدم التنفيذات أيضًا نقطة تحقق أكبر عند \(m=10\). فبترديد \(x^6\) لدينا

$$Q(x)^{10}\equiv 1+30x+455x^2+4640x^3+35715x^4+220906x^5,$$

ومنها

$$T(10)=1+30\cdot 5+455\cdot 10+4640\cdot 10+35715\cdot 5+220906=450582.$$

وبعد الضرب في \(7^{10}\) نحصل على

$$7^{10}T(10)=127278262644918,$$

وهو نفس مقدار التحقق العددي المستخدم داخل التنفيذ.

كيف يعمل الكود

تتبع تطبيقات C++ وPython وJava الخطة نفسها. فهي تمثل كل كثير حدود مقتطع بمصفوفة من ستة معاملات، ثم تضرب هذه المصفوفات بطريقة الالتفاف مع حذف كل ما يتجاوز الدرجة \(5\) فورًا.

بعد ذلك يُرفع كثير الحدود الأساسي إلى القوة \(142857\) بالرفع السريع للأس. وعندما تُعرف المعاملات الستة الصحيحة، تكوّن التنفيذات المجموع الموزون باستخدام الصف السادس من مثلث باسكال: \(1,5,10,10,5,1\).

وفي المرحلة الأخيرة يتحول العدد الصحيح الدقيق إلى الأساس \(7\) بالقسمة المتكررة، ثم تؤخذ أول عشرة أرقام. كما توجد نقطة تحقق عند الأس \(10\) للتأكد من أن حسابات الاقتطاع تعمل بدقة قبل الوصول إلى الأس الكبير.

تحليل التعقيد

كل عملية ضرب مقتطع تنفذ قدرًا ثابتًا من العمل، وهو \(21\) حاصل ضرب للمعاملات مع عمليات الجمع الموافقة. وبسبب الرفع السريع للأس، يكون عدد الضربات \(O(\log m)\). لذلك فإن التعقيد الكلي هو \(O(\log m)\) من عمليات الأعداد الصحيحة الكبيرة، مع \(O(1)\) من حيث تخزين المعاملات. أما الشيء الذي ينمو فعلًا فهو حجم الأعداد الصحيحة نفسها، لأن المعاملات والقيمة النهائية تُحسبان بدقة كاملة.

حواشٍ ومراجع

  1. صفحة المسألة في Project Euler: https://projecteuler.net/problem=831
  2. الدوال المولدة: Wikipedia - دالة مولدة
  3. Exponentiation by squaring: Wikipedia - Exponentiation by squaring
  4. نظرية ذات الحدين: Wikipedia - مبرهنة ذات الحدين
  5. نظرية متعدد الحدود: Wikipedia - Multinomial theorem