Problem Summary

A pseudo-random sequence produces digits \(T_n\in\{0,1,\dots,p-1\}\). These digits define a huge base-\(p\) integer

$$N=\sum_{n=0}^{q}T_n p^n.$$

The required quantity is the \(p\)-adic valuation

$$\nu_p(N!)$$

taken modulo \(p^e\). For the actual problem, \(p=61\), \(q=10^7\), \(e=10\), but the explanation below is written for general \(p,q,e\).

Mathematical Approach

1) Start from Legendre’s formula. For every positive integer \(N\),

$$\nu_p(N!)=\sum_{k\ge 1}\left\lfloor\frac{N}{p^k}\right\rfloor.$$

Since \(N\) has only \(q+1\) base-\(p\) digits, the sum actually stops at \(k=q\).

2) Expand each floor using the base-\(p\) digits. Because

$$N=\sum_{n=0}^{q}T_n p^n,$$

dividing by \(p^k\) and taking the floor simply drops the lowest \(k\) digits. Therefore

$$\left\lfloor\frac{N}{p^k}\right\rfloor=\sum_{n=k}^{q}T_n p^{\,n-k}.$$

This already shows why \(T_0\) never contributes to \(\nu_p(N!)\): every term in Legendre’s sum starts with division by at least one power of \(p\).

3) Swap the order of summation. Substitute the digit expansion into Legendre:

$$ \nu_p(N!)= \sum_{k=1}^{q}\sum_{n=k}^{q}T_n p^{\,n-k}. $$

Now fix a digit position \(n\). It contributes once for every \(k=1,2,\dots,n\). Writing \(j=n-k\), we obtain

$$ \nu_p(N!)= \sum_{n=1}^{q} T_n \sum_{j=0}^{n-1} p^j. $$

Equivalently, after swapping in the other direction,

$$ \nu_p(N!)= \sum_{j\ge 0} p^j \sum_{n=j+1}^{q} T_n. $$

This is the exact formula implemented by the code.

4) Why only the first \(e\) layers matter modulo \(p^e\). We only need the answer modulo \(p^e\). If \(j\ge e\), then \(p^j\) is already divisible by \(p^e\), so those terms vanish. Hence

$$ \nu_p(N!)\equiv \sum_{j=0}^{e-1} p^j S_j \pmod{p^e}, \qquad S_j=\sum_{n=j+1}^{q} T_n. $$

So the entire huge problem reduces to computing only \(e\) suffix sums of the digit sequence.

5) Why the code stores only a short prefix. Let

$$T_{\mathrm{all}}=\sum_{n=0}^{q}T_n.$$

Then each suffix can be written as

$$ S_j=T_{\mathrm{all}}-\sum_{n=0}^{j}T_n. $$

Therefore the solver only needs:

$$\text{(a) the total sum of all digits, and}\qquad \text{(b) prefix sums up to index }e-1.$$

This is why it stores

$$\texttt{first\_len}=\min(e,q+1)$$

prefix values, not the entire sequence.

6) Sequence generation. The digits are generated from

$$s_{n+1}=s_n^2 \bmod 50515093,\qquad s_0=290797,$$

and then

$$T_n=s_n\bmod p.$$

The algorithm streams the generator exactly once, accumulating the total digit sum and the first few prefix sums.

Worked Example

Take a toy base-\(5\) number with digits

$$T_0=2,\qquad T_1=4,\qquad T_2=1.$$

Then

$$N=2+4\cdot 5+1\cdot 25=47.$$

Legendre gives

$$\nu_5(47!)=\left\lfloor\frac{47}{5}\right\rfloor+\left\lfloor\frac{47}{25}\right\rfloor=9+1=10.$$

Now use the suffix formula:

$$S_0=T_1+T_2=5,\qquad S_1=T_2=1.$$

So

$$\nu_5(47!)=5^0S_0+5^1S_1=5+5=10,$$

exactly as expected.

Checks and Complexity

The source file includes the checkpoint

$$\mathrm{NF}(3,10000)\bmod 3^{20}=624955285,$$

and also compares the fast method against a brute-force big-integer computation for a smaller case.

Time complexity is

$$O(q+e),$$

because generating the digits costs \(O(q)\) and the final valuation sum costs \(O(e)\). Memory usage is

$$O(e),$$

since only a short prefix array and a few accumulators are stored.

Further Reading

  1. Problem page: https://projecteuler.net/problem=288
  2. Legendre’s formula: https://en.wikipedia.org/wiki/Legendre%27s_formula
  3. \(p\)-adic valuation: https://en.wikipedia.org/wiki/P-adic_valuation

Problemzusammenfassung

Eine Pseudozufallsfolge erzeugt Ziffern \(T_n\in\{0,1,\dots,p-1\}\). Daraus entsteht die riesige Zahl

$$N=\sum_{n=0}^{q}T_n p^n.$$

Gesucht ist die \(p\)-adische Bewertung

$$\nu_p(N!)$$

modulo \(p^e\). Im eigentlichen Problem sind \(p=61\), \(q=10^7\), \(e=10\).

Mathematischer Ansatz

1) Ausgangspunkt: Legendre.

$$\nu_p(N!)=\sum_{k\ge 1}\left\lfloor\frac{N}{p^k}\right\rfloor.$$

Wegen der endlichen Ziffernlänge endet diese Summe effektiv bei \(k=q\).

2) Jede Floor-Funktion in Basis \(p\) ausschreiben. Aus

$$N=\sum_{n=0}^{q}T_n p^n$$

folgt sofort

$$\left\lfloor\frac{N}{p^k}\right\rfloor=\sum_{n=k}^{q}T_n p^{n-k}.$$

Die unteren \(k\) Ziffern fallen einfach weg. Dadurch sieht man auch direkt: \(T_0\) trägt nie zu \(\nu_p(N!)\) bei.

3) Summen vertauschen. Einsetzen in Legendre liefert

$$ \nu_p(N!)= \sum_{k=1}^{q}\sum_{n=k}^{q}T_n p^{n-k}. $$

Fixiert man nun \(n\), so erscheint \(T_n\) genau für \(k=1,\dots,n\). Mit \(j=n-k\) ergibt sich

$$ \nu_p(N!)= \sum_{n=1}^{q}T_n\sum_{j=0}^{n-1}p^j. $$

Oder äquivalent

$$ \nu_p(N!)= \sum_{j\ge 0}p^j\sum_{n=j+1}^{q}T_n. $$

4) Warum modulo \(p^e\) nur \(j<e\) zählt. Sobald \(j\ge e\), ist \(p^j\) bereits durch \(p^e\) teilbar. Also bleibt

$$ \nu_p(N!)\equiv \sum_{j=0}^{e-1}p^jS_j \pmod{p^e}, \qquad S_j=\sum_{n=j+1}^{q}T_n. $$

5) Warum nur ein kurzer Präfix gespeichert wird. Mit

$$T_{\mathrm{all}}=\sum_{n=0}^{q}T_n$$

gilt

$$S_j=T_{\mathrm{all}}-\sum_{n=0}^{j}T_n.$$

Damit braucht der Code nur die Gesamtsumme aller Ziffern und Präfixsummen bis Index \(e-1\). Genau deshalb wird

$$\texttt{first\_len}=\min(e,q+1)$$

verwendet.

6) Erzeugung der Ziffern.

$$s_{n+1}=s_n^2 \bmod 50515093,\qquad s_0=290797,\qquad T_n=s_n\bmod p.$$

Die Folge wird nur einmal gestreamt.

Durchgerechnetes Beispiel

Nimm in Basis \(5\) die Ziffern

$$T_0=2,\qquad T_1=4,\qquad T_2=1.$$

Dann ist

$$N=2+4\cdot 5+1\cdot 25=47.$$

Legendre ergibt

$$\nu_5(47!)=\left\lfloor\frac{47}{5}\right\rfloor+\left\lfloor\frac{47}{25}\right\rfloor=9+1=10.$$

Mit den Suffixsummen:

$$S_0=T_1+T_2=5,\qquad S_1=T_2=1,$$

also

$$\nu_5(47!)=5^0S_0+5^1S_1=5+5=10.$$

Checks und Komplexität

Im Quelltext steht der Checkpoint

$$\mathrm{NF}(3,10000)\bmod 3^{20}=624955285,$$

zusätzlich zu einem Brute-Force-Vergleich für einen kleineren Fall.

Die Laufzeit ist

$$O(q+e),$$

der Speicherbedarf

$$O(e).$$

Weiterführende Hinweise

  1. Problem: https://projecteuler.net/problem=288
  2. Formel von Legendre: https://en.wikipedia.org/wiki/Legendre%27s_formula
  3. \(p\)-adische Bewertung: https://de.wikipedia.org/wiki/P-adische_Zahl

Problem Özeti

Bir pseudo-random dizi \(T_n\in\{0,1,\dots,p-1\}\) basamaklarını üretir. Bu basamaklar

$$N=\sum_{n=0}^{q}T_n p^n$$

şeklinde çok büyük bir \(p\)-tabanlı sayı tanımlar. Aranan değer

$$\nu_p(N!)$$

olup sonuç \(p^e\) modunda alınır. Asıl problemde \(p=61\), \(q=10^7\), \(e=10\)'dur.

Matematiksel Yaklaşım

1) Başlangıç noktası: Legendre formülü.

$$\nu_p(N!)=\sum_{k\ge 1}\left\lfloor\frac{N}{p^k}\right\rfloor.$$

\(N\)'nin yalnızca \(q+1\) basamağı olduğundan bu toplam gerçekte \(k=q\)'da biter.

2) Her floor terimini basamaklarla aç. Çünkü

$$N=\sum_{n=0}^{q}T_n p^n,$$

bölüp floor alınca en alt \(k\) basamak düşer:

$$\left\lfloor\frac{N}{p^k}\right\rfloor=\sum_{n=k}^{q}T_n p^{n-k}.$$

Buradan \(T_0\)'ın neden hiç katkı vermediği de açıkça görülür.

3) Toplamları yer değiştir. Legendre içine yerleştirince

$$ \nu_p(N!)= \sum_{k=1}^{q}\sum_{n=k}^{q}T_n p^{n-k} $$

elde edilir. Sabit bir \(n\) için \(T_n\), \(k=1,\dots,n\) boyunca görünür. \(j=n-k\) yazarsak

$$ \nu_p(N!)= \sum_{n=1}^{q}T_n\sum_{j=0}^{n-1}p^j $$

ve eşdeğer olarak

$$ \nu_p(N!)= \sum_{j\ge 0}p^j\sum_{n=j+1}^{q}T_n $$

olur. Kodun çekirdek fikri tam budur.

4) Neden mod \(p^e\) altında sadece ilk \(e\) katman kalır? Eğer \(j\ge e\) ise \(p^j\), zaten \(p^e\)'ye tam bölünür. Bu yüzden

$$ \nu_p(N!)\equiv \sum_{j=0}^{e-1}p^jS_j \pmod{p^e}, \qquad S_j=\sum_{n=j+1}^{q}T_n $$

yeterlidir. Yani bütün dev problem sadece \(e\) tane suffix toplamına indirgenir.

5) Kod neden kısa bir prefix tutuyor? Toplam basamak toplamını

$$T_{\mathrm{all}}=\sum_{n=0}^{q}T_n$$

olarak yazarsak

$$S_j=T_{\mathrm{all}}-\sum_{n=0}^{j}T_n$$

olur. Bu nedenle kodun ihtiyacı olan şey yalnızca:

$$\text{(a) tüm basamakların toplamı,}\qquad \text{(b) yalnızca ilk }e\text{ kadar prefix toplamı.}$$

Bu yüzden

$$\texttt{first\_len}=\min(e,q+1)$$

saklanır; bütün dizi tutulmaz.

6) Dizinin üretimi.

$$s_{n+1}=s_n^2 \bmod 50515093,\qquad s_0=290797,\qquad T_n=s_n\bmod p.$$

Algoritma bu üreteci yalnızca bir kez akar şekilde çalıştırır.

Çalışan Örnek

Taban \(5\) için

$$T_0=2,\qquad T_1=4,\qquad T_2=1$$

olsun. O zaman

$$N=2+4\cdot 5+1\cdot 25=47.$$

Legendre formülünden

$$\nu_5(47!)=\left\lfloor\frac{47}{5}\right\rfloor+\left\lfloor\frac{47}{25}\right\rfloor=9+1=10$$

çıkar. Suffix toplam formülü ise

$$S_0=T_1+T_2=5,\qquad S_1=T_2=1$$

verir ve

$$\nu_5(47!)=5^0S_0+5^1S_1=5+5=10$$

aynı sonucu üretir.

Kontroller ve Karmaşıklık

Kaynak dosyadaki checkpoint şunu doğrular:

$$\mathrm{NF}(3,10000)\bmod 3^{20}=624955285.$$

Ayrıca daha küçük bir örnekte brute-force büyük tamsayı hesabıyla çapraz kontrol yapılır.

Zaman karmaşıklığı

$$O(q+e),$$

bellek karmaşıklığı ise

$$O(e)$$

olarak kalır.

İleri Okuma

  1. Problem metni: https://projecteuler.net/problem=288
  2. Legendre formülü: https://en.wikipedia.org/wiki/Legendre%27s_formula
  3. \(p\)-adik değerleme: https://en.wikipedia.org/wiki/P-adic_valuation

Resumen del Problema

Una secuencia pseudoaleatoria produce dígitos \(T_n\in\{0,1,\dots,p-1\}\). Con ellos se define el enorme entero en base \(p\)

$$N=\sum_{n=0}^{q}T_n p^n.$$

Se busca la valoración \(p\)-ádica

$$\nu_p(N!)$$

módulo \(p^e\).

Enfoque Matemático

1) Punto de partida: Legendre.

$$\nu_p(N!)=\sum_{k\ge 1}\left\lfloor\frac{N}{p^k}\right\rfloor.$$

2) Expandir cada floor con las cifras base \(p\). Como

$$N=\sum_{n=0}^{q}T_n p^n,$$

tenemos

$$\left\lfloor\frac{N}{p^k}\right\rfloor=\sum_{n=k}^{q}T_n p^{n-k}.$$

Esto también muestra por qué \(T_0\) nunca contribuye.

3) Reordenar la suma. Sustituyendo en Legendre:

$$ \nu_p(N!)= \sum_{k=1}^{q}\sum_{n=k}^{q}T_n p^{n-k}. $$

Fijando \(n\) y usando \(j=n-k\), obtenemos

$$ \nu_p(N!)= \sum_{n=1}^{q}T_n\sum_{j=0}^{n-1}p^j =\sum_{j\ge 0}p^j\sum_{n=j+1}^{q}T_n. $$

4) Truncación módulo \(p^e\). Si \(j\ge e\), entonces \(p^j\) ya es múltiplo de \(p^e\), así que

$$ \nu_p(N!)\equiv \sum_{j=0}^{e-1}p^jS_j \pmod{p^e}, \qquad S_j=\sum_{n=j+1}^{q}T_n. $$

5) Por qué el código guarda solo un prefijo corto. Si

$$T_{\mathrm{all}}=\sum_{n=0}^{q}T_n,$$

entonces

$$S_j=T_{\mathrm{all}}-\sum_{n=0}^{j}T_n.$$

Por eso basta con la suma total y las sumas prefijo hasta \(e-1\).

6) Generación de la secuencia.

$$s_{n+1}=s_n^2 \bmod 50515093,\qquad s_0=290797,\qquad T_n=s_n\bmod p.$$

La secuencia se recorre una sola vez.

Ejemplo Resuelto

En base \(5\), toma

$$T_0=2,\qquad T_1=4,\qquad T_2=1.$$

Entonces

$$N=2+4\cdot5+1\cdot25=47.$$

Legendre da

$$\nu_5(47!)=\left\lfloor\frac{47}{5}\right\rfloor+\left\lfloor\frac{47}{25}\right\rfloor=9+1=10.$$

Por la fórmula de sufijos,

$$S_0=T_1+T_2=5,\qquad S_1=T_2=1,$$

y así

$$\nu_5(47!)=5^0S_0+5^1S_1=5+5=10.$$

Controles y Complejidad

El código incluye el checkpoint

$$\mathrm{NF}(3,10000)\bmod 3^{20}=624955285,$$

además de una verificación brute force para un caso pequeño.

La complejidad temporal es

$$O(q+e),$$

y la memoria es

$$O(e).$$

Lecturas

  1. Problema: https://projecteuler.net/problem=288
  2. Fórmula de Legendre: https://es.wikipedia.org/wiki/Fórmula_de_Legendre
  3. Valoración \(p\)-ádica: https://es.wikipedia.org/wiki/Valoración_p-ádica

问题概述

伪随机序列生成数字 \(T_n\in\{0,1,\dots,p-1\}\),从而构造出巨大的 \(p\) 进制整数

$$N=\sum_{n=0}^{q}T_n p^n.$$

要求计算

$$\nu_p(N!)$$

并对 \(p^e\) 取模。

数学方法

1) 从 Legendre 公式出发。

$$\nu_p(N!)=\sum_{k\ge 1}\left\lfloor\frac{N}{p^k}\right\rfloor.$$

2) 用 \(p\) 进制数字展开每一个 floor。 因为

$$N=\sum_{n=0}^{q}T_n p^n,$$

所以

$$\left\lfloor\frac{N}{p^k}\right\rfloor=\sum_{n=k}^{q}T_n p^{n-k}.$$

这也立刻解释了为什么 \(T_0\) 从不贡献到 \(\nu_p(N!)\)。

3) 交换求和顺序。

$$ \nu_p(N!)= \sum_{k=1}^{q}\sum_{n=k}^{q}T_n p^{n-k}. $$

固定 \(n\),再令 \(j=n-k\),可得

$$ \nu_p(N!)= \sum_{n=1}^{q}T_n\sum_{j=0}^{n-1}p^j =\sum_{j\ge 0}p^j\sum_{n=j+1}^{q}T_n. $$

4) 为什么模 \(p^e\) 只需要前 \(e\) 层。 当 \(j\ge e\) 时,\(p^j\) 已经被 \(p^e\) 整除,因此这些项在模 \(p^e\) 下全部消失。于是

$$ \nu_p(N!)\equiv \sum_{j=0}^{e-1}p^jS_j \pmod{p^e}, \qquad S_j=\sum_{n=j+1}^{q}T_n. $$

5) 为什么代码只保存很短的前缀和。

$$T_{\mathrm{all}}=\sum_{n=0}^{q}T_n,$$

$$S_j=T_{\mathrm{all}}-\sum_{n=0}^{j}T_n.$$

所以只要保存所有数字总和,以及前 \(e\) 项以内的前缀和,就足够恢复全部需要的 \(S_j\)。

6) 数列生成。

$$s_{n+1}=s_n^2 \bmod 50515093,\qquad s_0=290797,\qquad T_n=s_n\bmod p.$$

算法只顺序扫描这条序列一次。

工作示例

取一个 \(5\) 进制玩具例子:

$$T_0=2,\qquad T_1=4,\qquad T_2=1.$$

$$N=2+4\cdot5+1\cdot25=47.$$

由 Legendre 公式,

$$\nu_5(47!)=\left\lfloor\frac{47}{5}\right\rfloor+\left\lfloor\frac{47}{25}\right\rfloor=9+1=10.$$

而后缀公式给出

$$S_0=T_1+T_2=5,\qquad S_1=T_2=1,$$

因此

$$\nu_5(47!)=5^0S_0+5^1S_1=5+5=10,$$

两种方法完全一致。

校验与复杂度

源码中包含如下 checkpoint:

$$\mathrm{NF}(3,10000)\bmod 3^{20}=624955285,$$

并且还会在一个更小的案例上与 brute-force 大整数方法交叉验证。

时间复杂度为

$$O(q+e),$$

空间复杂度为

$$O(e).$$

延伸阅读

  1. 题目页面: https://projecteuler.net/problem=288
  2. Legendre 公式: https://zh.wikipedia.org/wiki/勒让德公式
  3. \(p\)-进赋值: https://en.wikipedia.org/wiki/P-adic_valuation

Краткое описание

Псевдослучайная последовательность порождает цифры \(T_n\in\{0,1,\dots,p-1\}\), из которых строится огромное число в базе \(p\):

$$N=\sum_{n=0}^{q}T_n p^n.$$

Требуется вычислить

$$\nu_p(N!)$$

по модулю \(p^e\).

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

1) Стартуем с формулы Лежандра.

$$\nu_p(N!)=\sum_{k\ge 1}\left\lfloor\frac{N}{p^k}\right\rfloor.$$

2) Разложим каждую floor-функцию по цифрам. Так как

$$N=\sum_{n=0}^{q}T_n p^n,$$

получаем

$$\left\lfloor\frac{N}{p^k}\right\rfloor=\sum_{n=k}^{q}T_n p^{n-k}.$$

Отсюда сразу видно, почему \(T_0\) не входит в \(\nu_p(N!)\).

3) Переставим суммы.

$$ \nu_p(N!)= \sum_{k=1}^{q}\sum_{n=k}^{q}T_n p^{n-k}. $$

Фиксируя \(n\) и полагая \(j=n-k\), получаем

$$ \nu_p(N!)= \sum_{n=1}^{q}T_n\sum_{j=0}^{n-1}p^j =\sum_{j\ge 0}p^j\sum_{n=j+1}^{q}T_n. $$

4) Усечение по модулю \(p^e\). При \(j\ge e\) множитель \(p^j\) уже кратен \(p^e\), поэтому остаётся только

$$ \nu_p(N!)\equiv \sum_{j=0}^{e-1}p^jS_j \pmod{p^e}, \qquad S_j=\sum_{n=j+1}^{q}T_n. $$

5) Почему достаточно короткого префикса. Если

$$T_{\mathrm{all}}=\sum_{n=0}^{q}T_n,$$

то

$$S_j=T_{\mathrm{all}}-\sum_{n=0}^{j}T_n.$$

Значит, программе нужна только общая сумма всех цифр и префиксные суммы до индекса \(e-1\).

6) Генерация последовательности.

$$s_{n+1}=s_n^2 \bmod 50515093,\qquad s_0=290797,\qquad T_n=s_n\bmod p.$$

Последовательность читается ровно один раз.

Работающий пример

Пусть в базе \(5\)

$$T_0=2,\qquad T_1=4,\qquad T_2=1.$$

Тогда

$$N=2+4\cdot5+1\cdot25=47.$$

По Лежандру

$$\nu_5(47!)=\left\lfloor\frac{47}{5}\right\rfloor+\left\lfloor\frac{47}{25}\right\rfloor=9+1=10.$$

По формуле через суффиксы

$$S_0=T_1+T_2=5,\qquad S_1=T_2=1,$$

и потому

$$\nu_5(47!)=5^0S_0+5^1S_1=5+5=10.$$

Проверки и сложность

В исходнике есть checkpoint

$$\mathrm{NF}(3,10000)\bmod 3^{20}=624955285,$$

а также brute-force сверка на меньшем тесте.

Временная сложность равна

$$O(q+e),$$

пространственная

$$O(e).$$

Дополнительные материалы

  1. Условие: https://projecteuler.net/problem=288
  2. Формула Лежандра: https://ru.wikipedia.org/wiki/Формула_Лежандра
  3. \(p\)-адическая оценка: https://en.wikipedia.org/wiki/P-adic_valuation

ملخص المسألة

تولّد سلسلة pseudo-random أرقامًا \(T_n\in\{0,1,\dots,p-1\}\)، ومن هذه الأرقام نكوّن العدد الضخم

$$N=\sum_{n=0}^{q}T_n p^n.$$

المطلوب هو حساب

$$\nu_p(N!)$$

بترديد \(p^e\).

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

1) نبدأ بصيغة ليجاندر.

$$\nu_p(N!)=\sum_{k\ge 1}\left\lfloor\frac{N}{p^k}\right\rfloor.$$

2) نفك كل حد باستعمال أرقام الأساس \(p\). بما أن

$$N=\sum_{n=0}^{q}T_n p^n,$$

فإن

$$\left\lfloor\frac{N}{p^k}\right\rfloor=\sum_{n=k}^{q}T_n p^{n-k}.$$

ومن هنا يظهر فورًا أن \(T_0\) لا يساهم أبدًا في \(\nu_p(N!)\).

3) نبدّل ترتيب الجمع.

$$ \nu_p(N!)= \sum_{k=1}^{q}\sum_{n=k}^{q}T_n p^{n-k}. $$

وبتثبيت \(n\) وكتابة \(j=n-k\) نحصل على

$$ \nu_p(N!)= \sum_{n=1}^{q}T_n\sum_{j=0}^{n-1}p^j =\sum_{j\ge 0}p^j\sum_{n=j+1}^{q}T_n. $$

4) القص بترديد \(p^e\). عندما \(j\ge e\)، يكون \(p^j\) من مضاعفات \(p^e\)، ولذلك لا تبقى إلا الحدود

$$ \nu_p(N!)\equiv \sum_{j=0}^{e-1}p^jS_j \pmod{p^e}, \qquad S_j=\sum_{n=j+1}^{q}T_n. $$

5) لماذا يكفي تخزين prefix قصير. إذا كانت

$$T_{\mathrm{all}}=\sum_{n=0}^{q}T_n,$$

فإن

$$S_j=T_{\mathrm{all}}-\sum_{n=0}^{j}T_n.$$

إذًا يحتاج الكود فقط إلى مجموع جميع الأرقام وإلى prefix sums لأول \(e\) حدود تقريبًا، لا إلى السلسلة كلها.

6) توليد السلسلة.

$$s_{n+1}=s_n^2 \bmod 50515093,\qquad s_0=290797,\qquad T_n=s_n\bmod p.$$

وتتم معالجة هذه السلسلة مرورًا واحدًا فقط.

مثال عملي

لنأخذ في الأساس \(5\):

$$T_0=2,\qquad T_1=4,\qquad T_2=1.$$

إذن

$$N=2+4\cdot5+1\cdot25=47.$$

ومن صيغة ليجاندر

$$\nu_5(47!)=\left\lfloor\frac{47}{5}\right\rfloor+\left\lfloor\frac{47}{25}\right\rfloor=9+1=10.$$

أما بصيغة suffix sums فنجد

$$S_0=T_1+T_2=5,\qquad S_1=T_2=1,$$

ومن ثم

$$\nu_5(47!)=5^0S_0+5^1S_1=5+5=10.$$

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

يتضمن الملف نقطة تحقق:

$$\mathrm{NF}(3,10000)\bmod 3^{20}=624955285,$$

كما يجري مقارنة مع brute-force على حالة أصغر.

التعقيد الزمني هو

$$O(q+e),$$

والذاكرة

$$O(e).$$

مراجع إضافية

  1. صفحة المسألة: https://projecteuler.net/problem=288
  2. صيغة Legendre: https://en.wikipedia.org/wiki/Legendre%27s_formula
  3. التقييم \(p\)-adic: https://en.wikipedia.org/wiki/P-adic_valuation