Problem Summary

Let

$$p=p_1p_2p_3\cdots$$

be an infinite random decimal stream, where each digit is chosen independently and uniformly from \(\{0,\dots,9\}\).

For a positive integer \(n\) with decimal representation

$$s=s_1s_2\cdots s_d,$$

let \(k\) be the first position where the block \(s\) appears in the stream. The problem asks for

$$\sum_{m=2}^{999999} g\!\left(\left\lfloor\frac{10^{16}}{m}\right\rfloor\right),$$

where \(g(n)=\mathbb E[k]\).

Mathematical Approach

1) End position is more convenient than start position.

If the first occurrence of \(s\) starts at position \(k\), then it ends at

$$T_{\mathrm{end}}=k+d-1.$$

So once we know the expected ending index, we recover the required quantity by

$$g(n)=\mathbb E[T_{\mathrm{end}}]-d+1.$$

This is why the code first computes an expected end position and only subtracts \(d-1\) at the very end.

2) KMP states give the exact Markov chain.

State \(i\in\{0,\dots,d\}\) means that the longest suffix of the digits seen so far equals the prefix \(s_1\cdots s_i\). State \(d\) is absorbing because the pattern has already appeared.

If \(E_i\) is the expected number of additional digits needed to reach state \(d\), then the exact linear system is

$$E_d=0,$$

$$E_i=1+\frac1{10}\sum_{x=0}^{9} E_{\delta(i,x)} \qquad (0\le i\lt d),$$

where \(\delta(i,x)\) is the usual KMP transition after reading digit \(x\).

So the problem is really an absorbing Markov chain on the prefix-function automaton.

3) The whole system collapses to the border chain.

Let

$$d=\ell_0 \gt \ell_1 \gt \ell_2 \gt \cdots \gt \ell_t \gt 0$$

be the lengths obtained by starting at \(d\) and repeatedly following the KMP failure link

$$\ell_{j+1}=\pi[\ell_j-1].$$

These are exactly the lengths of the pattern itself and all its non-empty proper borders.

The standard exact solution of the KMP expectation system is

$$\mathbb E[T_{\mathrm{end}}]=\sum_{j=0}^{t}10^{\ell_j}.$$

Equivalently,

$$g(n)=\sum_{j=0}^{t}10^{\ell_j}-d+1.$$

4) Why borders are the only overlaps that matter.

If the word had no self-overlap, every fresh full hit would need an average of \(10^d\) ending positions, so we would simply get \(\mathbb E[T_{\mathrm{end}}]=10^d\).

What changes this is overlap. After reading many digits, the automaton may fail to complete the word, yet still keep a suffix that is also a prefix of the pattern. The only suffix lengths that can survive in this way are the border lengths found by the prefix-function chain.

Those recyclable overlaps contribute the extra terms \(10^{\ell_1},10^{\ell_2},\dots\). No other state survives in the final closed form. That is why the implementation does not solve a dense linear system; it only walks the border chain.

5) Worked example: \(n=535\).

The decimal word is \(s=\texttt{535}\), so \(d=3\). Its prefix function is

$$\pi=[0,0,1],$$

hence the border chain is

$$3\to1\to0.$$

Therefore

$$\mathbb E[T_{\mathrm{end}}]=10^3+10^1=1010,$$

and

$$g(535)=1010-3+1=1008.$$

This matches the value given in the statement and the checkpoint in the C++ code.

6) The Markov equations for \(535\).

If we really write the state equations, with states \(0,1,2,3\) for matched prefixes \(\emptyset,\texttt{5},\texttt{53},\texttt{535}\), we obtain

$$E_3=0,$$

$$E_2=1+\frac9{10}E_0+\frac1{10}E_3=1+\frac9{10}E_0,$$

$$E_1=1+\frac8{10}E_0+\frac1{10}E_1+\frac1{10}E_2,$$

$$E_0=1+\frac9{10}E_0+\frac1{10}E_1.$$

Solving these gives

$$E_0=1010.$$

So the border formula is not a heuristic shortcut; it is the exact closed form of the full automaton system.

7) Another quick example: a word with no border.

For \(s=\texttt{12}\), there is no non-empty proper border. The chain contains only \(\ell_0=2\), hence

$$\mathbb E[T_{\mathrm{end}}]=10^2=100,\qquad g(12)=100-2+1=99.$$

This is exactly what we expect for a two-digit block with no overlap bonus.

8) Why \(g(n)\) is automatically an integer.

The formula uses only integer powers of \(10\) and an integer correction \(d-1\):

$$g(n)=\left(\sum_j 10^{\ell_j}\right)-d+1.$$

So the integrality of \(g(n)\), which looks surprising in the problem statement, becomes completely transparent.

9) What the code actually does.

For each query value

$$q=\left\lfloor\frac{10^{16}}{m}\right\rfloor,$$

the solver:

a) converts \(q\) to its decimal string \(s\),

b) builds the KMP prefix function \(\pi\) in \(O(d)\),

c) walks the chain

$$d,\ \pi[d-1],\ \pi[\pi[d-1]-1],\dots$$

and adds the precomputed powers \(10^{\ell}\),

d) subtracts \(d-1\) to turn expected end position into expected start position.

This is exactly the loop for (len = d; len > 0; len = pi[len - 1]) expected_end += pow10[len];.

Algorithm

1) Precompute \(10^0,10^1,\dots,10^{19}\).

2) For each \(m=2,\dots,999999\), set \(q=\lfloor 10^{16}/m\rfloor\).

3) Build the prefix function of the decimal expansion of \(q\).

4) Sum \(10^{\ell}\) over the full border chain.

5) Convert expected end index to \(g(q)\) by subtracting \(d-1\).

6) Accumulate the result in a 128-bit integer.

Complexity Analysis

There are

$$Q=999998$$

queries, and each queried number has at most \(16\) decimal digits. Therefore the total running time is

$$O\!\left(\sum_{m=2}^{999999} d_m\right)=O(16Q),$$

which is effectively linear in the number of queries. Memory per query is \(O(d)\), again at most \(16\) integers.

Checks And Final Result

The implementation checks the two values stated by the problem:

$$g(535)=1008,$$

$$\sum_{n=2}^{999} g\!\left(\left\lfloor\frac{10^6}{n}\right\rfloor\right)=27280188.$$

The final answer produced by the program is

$$542934735751917735.$$

Further Reading

  1. Problem page: https://projecteuler.net/problem=316
  2. Knuth-Morris-Pratt algorithm: https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
  3. Prefix function and borders: https://cp-algorithms.com/string/prefix-function.html

Problemzusammenfassung

Sei

$$p=p_1p_2p_3\cdots$$

ein unendlicher Zufallsstrom von Dezimalziffern. Fuer eine positive ganze Zahl \(n\) mit Dezimalwort

$$s=s_1s_2\cdots s_d$$

sei \(k\) die erste Startposition, an der \(s\) im Strom auftaucht. Gesucht ist

$$\sum_{m=2}^{999999} g\!\left(\left\lfloor\frac{10^{16}}{m}\right\rfloor\right),$$

wobei \(g(n)=\mathbb E[k]\).

Mathematischer Ansatz

1) Endposition statt Startposition.

Endet das erste Auftreten bei

$$T_{\mathrm{end}}=k+d-1,$$

dann gilt

$$g(n)=\mathbb E[T_{\mathrm{end}}]-d+1.$$

Darum berechnet der Code zuerst die erwartete Endposition.

2) KMP-Zustaende bilden die exakte Markov-Kette.

Zustand \(i\) bedeutet: Das laengste Suffix der bisher gelesenen Ziffern ist genau das Praefix \(s_1\cdots s_i\). Zustand \(d\) ist absorbierend.

Mit \(E_i\) als erwarteter Restanzahl von Ziffern bis zum ersten Volltreffer gilt

$$E_d=0,$$

$$E_i=1+\frac1{10}\sum_{x=0}^{9}E_{\delta(i,x)} \qquad (0\le i\lt d),$$

wobei \(\delta(i,x)\) der uebliche KMP-Uebergang ist.

3) Die Loesung reduziert sich auf die Border-Kette.

Folgt man wiederholt den Failure-Links der Praefixfunktion, erhaelt man

$$d=\ell_0 \gt \ell_1 \gt \cdots \gt \ell_t \gt 0.$$

Das sind genau die Laengen des ganzen Wortes und aller nichtleeren echten Border.

Die exakte geschlossene Form lautet

$$\mathbb E[T_{\mathrm{end}}]=\sum_{j=0}^{t}10^{\ell_j},$$

also

$$g(n)=\sum_{j=0}^{t}10^{\ell_j}-d+1.$$

4) Warum nur Border zaehlen.

Ohne Selbstueberlappung haette man einfach \(\mathbb E[T_{\mathrm{end}}]=10^d\). Zusaetzliche Terme entstehen nur dadurch, dass nach einem Fehlschlag oder nach einem Treffer ein Suffix uebrigbleibt, das zugleich ein Praefix des Musters ist. Genau diese wiederverwertbaren Ueberlappungen werden von der Border-Kette beschrieben.

5) Beispiel \(n=535\).

Hier ist \(s=\texttt{535}\), also \(d=3\), und

$$\pi=[0,0,1].$$

Die Border-Kette ist

$$3\to1\to0,$$

daher

$$\mathbb E[T_{\mathrm{end}}]=10^3+10^1=1010,$$

und somit

$$g(535)=1010-3+1=1008.$$

6) Volles Gleichungssystem fuer \(535\).

Mit KMP-Zustaenden \(0,1,2,3\) fuer \(\emptyset,\texttt{5},\texttt{53},\texttt{535}\) gilt

$$E_3=0,$$

$$E_2=1+\frac9{10}E_0,$$

$$E_1=1+\frac8{10}E_0+\frac1{10}E_1+\frac1{10}E_2,$$

$$E_0=1+\frac9{10}E_0+\frac1{10}E_1.$$

Die Loesung ist wieder \(E_0=1010\). Die Border-Formel ist also exakt, nicht nur eine Intuition.

7) Beispiel ohne Border.

Fuer \(s=\texttt{12}\) gibt es keinen nichtleeren echten Border. Also

$$\mathbb E[T_{\mathrm{end}}]=10^2=100,\qquad g(12)=99.$$

8) Warum \(g(n)\) immer ganzzahlig ist.

Aus

$$g(n)=\left(\sum_j10^{\ell_j}\right)-d+1$$

sieht man sofort: Nur ganze Zehnerpotenzen und eine ganze Korrektur treten auf.

9) Was der Code pro Anfrage macht.

Fuer

$$q=\left\lfloor\frac{10^{16}}{m}\right\rfloor$$

wird die Dezimaldarstellung gebildet, die Praefixfunktion in \(O(d)\) berechnet, dann die Kette

$$d,\ \pi[d-1],\ \pi[\pi[d-1]-1],\dots$$

durchlaufen und \(10^{\ell}\) aufsummiert. Danach wird \(d-1\) abgezogen.

Algorithmus

1) Zehnerpotenzen bis \(10^{19}\) vorkalkulieren.

2) Fuer \(m=2,\dots,999999\) den Wert \(q=\lfloor10^{16}/m\rfloor\) bestimmen.

3) Prefix-Funktion von \(q\) berechnen.

4) Ueber die Border-Kette alle \(10^{\ell}\) summieren.

5) Mit \(-d+1\) von Endindex zu Startindex wechseln.

6) Alles in einem 128-Bit-Akkumulator aufsummieren.

Komplexitaetsanalyse

Es gibt

$$Q=999998$$

Anfragen, und jede Zahl hat hoechstens \(16\) Stellen. Also ist die Gesamtzeit

$$O\!\left(\sum d_m\right)=O(16Q),$$

mit \(O(d)\) Speicher pro Anfrage.

Kontrollen Und Endergebnis

Der Code prueft

$$g(535)=1008,$$

$$\sum_{n=2}^{999} g\!\left(\left\lfloor\frac{10^6}{n}\right\rfloor\right)=27280188.$$

Das Endergebnis lautet

$$542934735751917735.$$

Weiterfuehrende Hinweise

  1. Problem: https://projecteuler.net/problem=316
  2. KMP-Algorithmus: https://de.wikipedia.org/wiki/Knuth-Morris-Pratt-Algorithmus
  3. Prefix-Funktion und Border: https://cp-algorithms.com/string/prefix-function.html

Problem Özeti

Rastgele secilen sonsuz bir onluk basamak akisi

$$p=p_1p_2p_3\cdots$$

veriliyor. Her basamak \(\{0,\dots,9\}\) kumesinden bagimsiz ve esit olasilikla geliyor.

Pozitif bir tam sayinin onluk yazimi

$$s=s_1s_2\cdots s_d$$

olsun. Bu blogun akista ilk goruldugu baslangic indisine \(k\) diyelim. Sorulan sey

$$\sum_{m=2}^{999999} g\!\left(\left\lfloor\frac{10^{16}}{m}\right\rfloor\right)$$

ve burada \(g(n)=\mathbb E[k]\).

Matematiksel Yaklaşım

1) Baslangic indisi yerine bitis indisini hesaplamak daha kolay.

Ilk gorulme \(k\) konumunda basliyorsa bitis indisi

$$T_{\mathrm{end}}=k+d-1$$

olur. Bu nedenle

$$g(n)=\mathbb E[T_{\mathrm{end}}]-d+1.$$

Kod da tam olarak bunu yapiyor: once beklenen bitis konumunu buluyor, sonra \(d-1\) cikariyor.

2) KMP durumlari problemi tam olarak modeller.

Durum \(i\), simdiye kadar okunan rakamlarin en uzun suffix'inin desenin ilk \(i\) rakamina esit oldugu anlamina gelir. Durum \(d\) absorb edici durumdur; cunku desen artik gorulmustur.

\(E_i\) bu durumdan itibaren ilk tam eslesmeye kadar gereken ek basamak sayisinin beklentisi olsun. O zaman tam denklem sistemi

$$E_d=0,$$

$$E_i=1+\frac1{10}\sum_{x=0}^{9}E_{\delta(i,x)} \qquad (0\le i\lt d)$$

seklindedir. Burada \(\delta(i,x)\), KMP otomatinin rakam \(x\) geldikten sonraki yeni durumudur.

3) Cozum border zincirine coker.

Prefix fonksiyonunun failure linklerini izleyince

$$d=\ell_0 \gt \ell_1 \gt \ell_2 \gt \cdots \gt \ell_t \gt 0$$

zinciri elde edilir. Bunlar desenin kendisinin ve tum bos olmayan proper border'larinin uzunluklaridir.

Bu otomat icin tam kapali formul

$$\mathbb E[T_{\mathrm{end}}]=\sum_{j=0}^{t}10^{\ell_j}$$

oldugundan

$$g(n)=\sum_{j=0}^{t}10^{\ell_j}-d+1$$

elde edilir.

4) Neden sadece border'lar onemli?

Eger desenin hic self-overlap'i olmasaydi beklenen bitis konumu sadece \(10^d\) olurdu. Ek terimler, basarisiz bir denemeden sonra desenin basiyla ayni olan bir suffix'in elde kalmasindan dogar. Boylesi yeniden kullanilabilir suffix uzunluklari tam olarak border uzunluklaridir. Bu yuzden kod butun durumlardan olusan lineer sistemi cozmek yerine sadece failure-link zincirini yurur.

5) Calisan ornek: \(n=535\).

Burada \(s=\texttt{535}\) ve \(d=3\). Prefix fonksiyonu

$$\pi=[0,0,1]$$

olur; dolayisiyla border zinciri

$$3\to1\to0$$

seklindedir. O halde

$$\mathbb E[T_{\mathrm{end}}]=10^3+10^1=1010,$$

ve

$$g(535)=1010-3+1=1008.$$

Bu, problem metnindeki ve C++ kodundaki checkpoint ile aynidir.

6) \(535\) icin tam Markov denklemleri.

Durumlar \(\emptyset,\texttt{5},\texttt{53},\texttt{535}\) icin sirasiyla \(0,1,2,3\) olsun. O zaman

$$E_3=0,$$

$$E_2=1+\frac9{10}E_0,$$

$$E_1=1+\frac8{10}E_0+\frac1{10}E_1+\frac1{10}E_2,$$

$$E_0=1+\frac9{10}E_0+\frac1{10}E_1.$$

Bu sistemin cozumu

$$E_0=1010$$

verir. Yani border formulu sezgisel bir kisayol degil, tam denklemin kapali bicimidir.

7) Border'i olmayan hizli ornek.

\(s=\texttt{12}\) icin bos olmayan proper border yoktur. Bu yuzden

$$\mathbb E[T_{\mathrm{end}}]=10^2=100,\qquad g(12)=99.$$

8) \(g(n)\) neden hep tam sayi?

Cunku formulumuz

$$g(n)=\left(\sum_j10^{\ell_j}\right)-d+1$$

yalnizca tam sayi kuvvetler ve tam sayi bir duzeltme icerir.

9) Kodun yaptigi sey tam olarak nedir?

Her

$$q=\left\lfloor\frac{10^{16}}{m}\right\rfloor$$

degeri icin:

a) sayiyi string'e cevirir,

b) \(O(d)\) zamanda prefix fonksiyonunu kurar,

c) su zinciri yurur:

$$d,\ \pi[d-1],\ \pi[\pi[d-1]-1],\dots$$

ve her adimda \(10^{\ell}\) ekler,

d) en sonda \(d-1\) cikarir.

Bu dogrudan su satira karsilik gelir: for (len = d; len > 0; len = pi[len - 1]) expected_end += pow10[len];.

Algoritma

1) \(10^0,\dots,10^{19}\) degerlerini once hesapla.

2) \(m=2,\dots,999999\) icin \(q=\lfloor10^{16}/m\rfloor\) bul.

3) \(q\)'nun onluk yazimi icin prefix fonksiyonunu kur.

4) Border zincirindeki tum \(10^{\ell}\) terimlerini topla.

5) \(d-1\) cikarip \(g(q)\)'yu elde et.

6) Tum degerleri 128-bit toplamda biriktir.

Karmaşıklık Analizi

Toplam

$$Q=999998$$

sorgu vardir ve her sorgunun uzunlugu en fazla \(16\) basamaktir. Dolayisiyla toplam zaman

$$O\!\left(\sum d_m\right)=O(16Q)$$

olur. Bellek ise sorgu basina \(O(d)\), yani pratikte sabit kadardir.

Kontroller Ve Nihai Sonuc

Kod su iki kontrolu yapar:

$$g(535)=1008,$$

$$\sum_{n=2}^{999} g\!\left(\left\lfloor\frac{10^6}{n}\right\rfloor\right)=27280188.$$

Nihai cevap

$$542934735751917735$$

olarak uretilir.

Ileri Okuma

  1. Problem metni: https://projecteuler.net/problem=316
  2. KMP algoritmasi: https://tr.wikipedia.org/wiki/Knuth-Morris-Pratt_algoritması
  3. Prefix-function ve border yapisi: https://cp-algorithms.com/string/prefix-function.html

Resumen del Problema

Sea

$$p=p_1p_2p_3\cdots$$

una secuencia infinita de digitos decimales equiprobables e independientes.

Para un entero positivo \(n\) con expansion decimal

$$s=s_1s_2\cdots s_d,$$

sea \(k\) la primera posicion inicial donde aparece ese bloque. Debemos calcular

$$\sum_{m=2}^{999999} g\!\left(\left\lfloor\frac{10^{16}}{m}\right\rfloor\right),$$

donde \(g(n)=\mathbb E[k]\).

Enfoque Matematico

1) Conviene trabajar con la posicion final.

Si la primera aparicion empieza en \(k\), termina en

$$T_{\mathrm{end}}=k+d-1.$$

Por tanto

$$g(n)=\mathbb E[T_{\mathrm{end}}]-d+1.$$

2) Estados KMP y cadena de Markov exacta.

El estado \(i\) significa que el sufijo mas largo visto hasta ahora coincide con el prefijo \(s_1\cdots s_i\). El estado \(d\) es absorbente.

Si \(E_i\) es la esperanza de digitos adicionales hasta la primera coincidencia completa, entonces

$$E_d=0,$$

$$E_i=1+\frac1{10}\sum_{x=0}^{9}E_{\delta(i,x)} \qquad (0\le i\lt d).$$

3) Todo se reduce a la cadena de bordes.

Siguiendo repetidamente los enlaces de fallo de la funcion prefijo obtenemos

$$d=\ell_0 \gt \ell_1 \gt \cdots \gt \ell_t \gt 0.$$

Esas son las longitudes del patron completo y de todos sus bordes propios no vacios.

La forma cerrada exacta es

$$\mathbb E[T_{\mathrm{end}}]=\sum_{j=0}^{t}10^{\ell_j},$$

de modo que

$$g(n)=\sum_{j=0}^{t}10^{\ell_j}-d+1.$$

4) Por que solo importan los bordes.

Sin auto-solapamientos tendriamos simplemente \(10^d\). Los terminos extra aparecen porque, tras un fallo, puede quedar un sufijo que ya coincide con un prefijo del patron. Esos sufijos reutilizables son exactamente los bordes enumerados por la cadena de KMP.

5) Ejemplo \(n=535\).

Aqui \(s=\texttt{535}\), \(d=3\), y

$$\pi=[0,0,1].$$

La cadena de bordes es

$$3\to1\to0,$$

por lo que

$$\mathbb E[T_{\mathrm{end}}]=10^3+10^1=1010,$$

y

$$g(535)=1010-3+1=1008.$$

6) Sistema completo para \(535\).

Con estados \(0,1,2,3\) para \(\emptyset,\texttt{5},\texttt{53},\texttt{535}\), se obtiene

$$E_3=0,$$

$$E_2=1+\frac9{10}E_0,$$

$$E_1=1+\frac8{10}E_0+\frac1{10}E_1+\frac1{10}E_2,$$

$$E_0=1+\frac9{10}E_0+\frac1{10}E_1.$$

La solucion es \(E_0=1010\), exactamente la formula por bordes.

7) Ejemplo sin borde propio.

Para \(s=\texttt{12}\) no hay borde propio no vacio, asi que

$$\mathbb E[T_{\mathrm{end}}]=10^2=100,\qquad g(12)=99.$$

8) Por que \(g(n)\) siempre es entero.

La formula

$$g(n)=\left(\sum_j10^{\ell_j}\right)-d+1$$

usa solo potencias enteras de \(10\) y una correccion entera.

9) Lo que hace el codigo.

Para cada

$$q=\left\lfloor\frac{10^{16}}{m}\right\rfloor,$$

convierte \(q\) en cadena, construye la funcion prefijo en \(O(d)\), recorre

$$d,\ \pi[d-1],\ \pi[\pi[d-1]-1],\dots$$

y suma las potencias \(10^{\ell}\). Luego resta \(d-1\).

Algoritmo

1) Precalcular \(10^0,\dots,10^{19}\).

2) Para \(m=2,\dots,999999\), calcular \(q=\lfloor10^{16}/m\rfloor\).

3) Construir la funcion prefijo de \(q\).

4) Sumar \(10^{\ell}\) en la cadena de bordes.

5) Restar \(d-1\) para obtener \(g(q)\).

6) Acumular todo en 128 bits.

Complejidad

Hay

$$Q=999998$$

consultas y cada cadena tiene a lo sumo \(16\) digitos. Luego el tiempo total es

$$O\!\left(\sum d_m\right)=O(16Q),$$

con memoria \(O(d)\) por consulta.

Comprobaciones Y Resultado Final

El programa verifica

$$g(535)=1008,$$

$$\sum_{n=2}^{999} g\!\left(\left\lfloor\frac{10^6}{n}\right\rfloor\right)=27280188.$$

La respuesta final es

$$542934735751917735.$$

Lecturas

  1. Problema: https://projecteuler.net/problem=316
  2. Algoritmo KMP: https://es.wikipedia.org/wiki/Algoritmo_de_búsqueda_de_cadenas_de_Knuth-Morris-Pratt
  3. Funcion prefijo y bordes: https://cp-algorithms.com/string/prefix-function.html

问题概述

$$p=p_1p_2p_3\cdots$$

是一个无限随机十进制串,每一位都在 \(\{0,\dots,9\}\) 中独立且等概率出现。

对一个正整数 \(n\),记其十进制表示为

$$s=s_1s_2\cdots s_d.$$

令 \(k\) 为这个块第一次在随机串中出现的起始位置。题目要求计算

$$\sum_{m=2}^{999999} g\!\left(\left\lfloor\frac{10^{16}}{m}\right\rfloor\right),$$

其中 \(g(n)=\mathbb E[k]\)。

数学方法

1)先算结束位置更方便。

如果第一次出现从位置 \(k\) 开始,那么它结束于

$$T_{\mathrm{end}}=k+d-1.$$

因此

$$g(n)=\mathbb E[T_{\mathrm{end}}]-d+1.$$

这正是代码最后要减去 \(d-1\) 的原因。

2)KMP 状态就是精确的 Markov 链。

状态 \(i\) 表示:目前读到的所有数字中,最长后缀恰好等于模式串前缀 \(s_1\cdots s_i\)。状态 \(d\) 是吸收态,因为模式已经完整出现。

若 \(E_i\) 表示从状态 \(i\) 到第一次完整匹配还需要读入的额外数字个数的期望,则有

$$E_d=0,$$

$$E_i=1+\frac1{10}\sum_{x=0}^{9}E_{\delta(i,x)} \qquad (0\le i\lt d),$$

其中 \(\delta(i,x)\) 是 KMP 自动机读入数字 \(x\) 后的新状态。

3)整个线性系统最终只剩 border 链。

从长度 \(d\) 出发,不断沿前缀函数失败指针回跳,会得到

$$d=\ell_0 \gt \ell_1 \gt \ell_2 \gt \cdots \gt \ell_t \gt 0.$$

这些正好是整个模式串以及全部非空真 border 的长度。

这个问题的精确闭式为

$$\mathbb E[T_{\mathrm{end}}]=\sum_{j=0}^{t}10^{\ell_j},$$

于是

$$g(n)=\sum_{j=0}^{t}10^{\ell_j}-d+1.$$

4)为什么只有 border 会留下贡献。

如果模式完全没有自重叠,那么第一次完整命中的期望结束位置就是 \(10^d\)。额外项来自“失败后仍然保留了一个可继续利用的前缀”。这种可回收的后缀长度,恰好就是 border 长度,而 prefix-function 链正是把这些长度全部列出来。

5)例子:\(n=535\)。

此时 \(s=\texttt{535}\),\(d=3\),前缀函数为

$$\pi=[0,0,1].$$

所以 border 链是

$$3\to1\to0.$$

因此

$$\mathbb E[T_{\mathrm{end}}]=10^3+10^1=1010,$$

从而

$$g(535)=1010-3+1=1008.$$

这与题目样例和代码检查完全一致。

6)把 \(535\) 的状态方程真的写出来。

用状态 \(0,1,2,3\) 分别表示 \(\emptyset,\texttt{5},\texttt{53},\texttt{535}\),则

$$E_3=0,$$

$$E_2=1+\frac9{10}E_0,$$

$$E_1=1+\frac8{10}E_0+\frac1{10}E_1+\frac1{10}E_2,$$

$$E_0=1+\frac9{10}E_0+\frac1{10}E_1.$$

解得

$$E_0=1010.$$

所以 border 公式并不是拍脑袋的简化,而是完整自动机方程的闭式结果。

7)没有 border 的快速例子。

例如 \(s=\texttt{12}\) 没有非空真 border,因此

$$\mathbb E[T_{\mathrm{end}}]=10^2=100,\qquad g(12)=99.$$

8)为什么 \(g(n)\) 一定是整数。

因为

$$g(n)=\left(\sum_j10^{\ell_j}\right)-d+1$$

只包含整数次幂和整数修正项。

9)代码的真实工作流。

对每个

$$q=\left\lfloor\frac{10^{16}}{m}\right\rfloor,$$

代码会:

a) 把 \(q\) 转成十进制字符串,

b) 在线性时间内构造 prefix function,

c) 沿着

$$d,\ \pi[d-1],\ \pi[\pi[d-1]-1],\dots$$

这条链累加 \(10^\ell\),

d) 最后减去 \(d-1\)。

算法

1) 预计算 \(10^0\) 到 \(10^{19}\)。

2) 对 \(m=2,\dots,999999\) 计算 \(q=\lfloor10^{16}/m\rfloor\)。

3) 构造 \(q\) 的前缀函数。

4) 遍历 border 链并累加 \(10^\ell\)。

5) 减去 \(d-1\),得到 \(g(q)\)。

6) 用 128 位整数累加总和。

复杂度分析

总共有

$$Q=999998$$

个查询,每个数最多 \(16\) 位,因此总时间复杂度为

$$O\!\left(\sum d_m\right)=O(16Q),$$

单次查询空间复杂度为 \(O(d)\)。

校验与最终结果

程序先验证

$$g(535)=1008,$$

以及

$$\sum_{n=2}^{999} g\!\left(\left\lfloor\frac{10^6}{n}\right\rfloor\right)=27280188.$$

最终答案为

$$542934735751917735.$$

延伸阅读

  1. 题目页面: https://projecteuler.net/problem=316
  2. KMP 算法: https://zh.wikipedia.org/wiki/Knuth-Morris-Pratt算法
  3. Prefix function 与 border: https://cp-algorithms.com/string/prefix-function.html

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

Пусть

$$p=p_1p_2p_3\cdots$$

это бесконечный случайный поток десятичных цифр, где каждая цифра из \(\{0,\dots,9\}\) выбирается независимо и равновероятно.

Для положительного целого \(n\) с десятичной записью

$$s=s_1s_2\cdots s_d$$

обозначим через \(k\) первую позицию начала, на которой этот блок появляется в потоке. Нужно вычислить

$$\sum_{m=2}^{999999} g\!\left(\left\lfloor\frac{10^{16}}{m}\right\rfloor\right),$$

где \(g(n)=\mathbb E[k]\).

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

1) Удобнее считать позицию конца.

Если первое вхождение начинается в \(k\), то заканчивается оно в

$$T_{\mathrm{end}}=k+d-1.$$

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

$$g(n)=\mathbb E[T_{\mathrm{end}}]-d+1.$$

2) Состояния KMP дают точную цепь Маркова.

Состояние \(i\) означает, что самый длинный суффикс уже прочитанной последовательности совпадает с префиксом \(s_1\cdots s_i\). Состояние \(d\) поглощающее.

Если \(E_i\) обозначает ожидаемое количество дополнительных цифр до первого полного совпадения, то

$$E_d=0,$$

$$E_i=1+\frac1{10}\sum_{x=0}^{9}E_{\delta(i,x)} \qquad (0\le i\lt d),$$

где \(\delta(i,x)\) - переход автомата KMP после чтения цифры \(x\).

3) Вся система схлопывается в цепочку бордеров.

Если идти по failure-link префикс-функции, получаем

$$d=\ell_0 \gt \ell_1 \gt \ell_2 \gt \cdots \gt \ell_t \gt 0.$$

Это длины самого слова и всех его непустых собственных бордеров.

Точная замкнутая формула такова:

$$\mathbb E[T_{\mathrm{end}}]=\sum_{j=0}^{t}10^{\ell_j},$$

а значит

$$g(n)=\sum_{j=0}^{t}10^{\ell_j}-d+1.$$

4) Почему важны только бордеры.

Без самоперекрытий мы получили бы просто \(10^d\). Дополнительные слагаемые появляются из-за того, что после неудачной попытки может сохраниться суффикс, который уже является префиксом шаблона. Ровно такие длины и перечисляет цепочка бордеров.

5) Пример \(n=535\).

Здесь \(s=\texttt{535}\), \(d=3\), и

$$\pi=[0,0,1].$$

Значит, цепочка бордеров имеет вид

$$3\to1\to0,$$

поэтому

$$\mathbb E[T_{\mathrm{end}}]=10^3+10^1=1010,$$

и

$$g(535)=1010-3+1=1008.$$

6) Полная система уравнений для \(535\).

Если состояния \(0,1,2,3\) соответствуют \(\emptyset,\texttt{5},\texttt{53},\texttt{535}\), то

$$E_3=0,$$

$$E_2=1+\frac9{10}E_0,$$

$$E_1=1+\frac8{10}E_0+\frac1{10}E_1+\frac1{10}E_2,$$

$$E_0=1+\frac9{10}E_0+\frac1{10}E_1.$$

Решение снова дает

$$E_0=1010.$$

Значит, формула через бордеры является точным замкнутым решением, а не эвристикой.

7) Быстрый пример без бордеров.

Для \(s=\texttt{12}\) непустых собственных бордеров нет, поэтому

$$\mathbb E[T_{\mathrm{end}}]=10^2=100,\qquad g(12)=99.$$

8) Почему \(g(n)\) всегда целое.

Из формулы

$$g(n)=\left(\sum_j10^{\ell_j}\right)-d+1$$

сразу видно: тут есть только целые степени десяти и целая поправка.

9) Что именно делает код.

Для каждого

$$q=\left\lfloor\frac{10^{16}}{m}\right\rfloor$$

он переводит число в строку, строит префикс-функцию за \(O(d)\), проходит по цепочке

$$d,\ \pi[d-1],\ \pi[\pi[d-1]-1],\dots$$

и суммирует \(10^\ell\), после чего вычитает \(d-1\).

Алгоритм

1) Предвычислить \(10^0,\dots,10^{19}\).

2) Для \(m=2,\dots,999999\) вычислить \(q=\lfloor10^{16}/m\rfloor\).

3) Построить префикс-функцию десятичной строки числа \(q\).

4) Просуммировать \(10^\ell\) по цепочке бордеров.

5) Перейти от конца к старту через \(-d+1\).

6) Накопить ответ в 128-битном целочисленном типе.

Сложность

Всего имеется

$$Q=999998$$

запросов, каждая строка имеет длину не больше \(16\). Поэтому общее время равно

$$O\!\left(\sum d_m\right)=O(16Q),$$

а память на один запрос равна \(O(d)\).

Проверки И Итоговый Ответ

Программа проверяет

$$g(535)=1008,$$

и

$$\sum_{n=2}^{999} g\!\left(\left\lfloor\frac{10^6}{n}\right\rfloor\right)=27280188.$$

Итоговый ответ:

$$542934735751917735.$$

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

  1. Условие задачи: https://projecteuler.net/problem=316
  2. Алгоритм Кнута-Морриса-Пратта: https://ru.wikipedia.org/wiki/Алгоритм_Кнута_—_Морриса_—_Пратта
  3. Префикс-функция и бордеры: https://cp-algorithms.com/string/prefix-function.html

ملخص المسألة

لدينا تدفق عشري عشوائي لا نهائي

$$p=p_1p_2p_3\cdots$$

بحيث تُختار كل خانة من \(\{0,\dots,9\}\) بشكل مستقل وباحتمال متساو.

لعدد صحيح موجب \(n\) ذي التمثيل العشري

$$s=s_1s_2\cdots s_d,$$

لنرمز بـ \(k\) إلى أول موضع بداية يظهر فيه هذا النمط. المطلوب هو حساب

$$\sum_{m=2}^{999999} g\!\left(\left\lfloor\frac{10^{16}}{m}\right\rfloor\right),$$

حيث \(g(n)=\mathbb E[k]\).

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

1) الأسهل هو حساب موضع النهاية أولاً.

إذا بدأ أول ظهور عند الموضع \(k\)، فإنه ينتهي عند

$$T_{\mathrm{end}}=k+d-1.$$

إذن

$$g(n)=\mathbb E[T_{\mathrm{end}}]-d+1.$$

ولهذا يحسب الكود قيمة نهاية الظهور أولاً ثم يطرح \(d-1\).

2) حالات KMP تعطي سلسلة Markov الدقيقة.

الحالة \(i\) تعني أن أطول لاحقة مما قرأناه حتى الآن تساوي بادئة النمط \(s_1\cdots s_i\). والحالة \(d\) حالة امتصاص لأن النمط ظهر كاملاً.

إذا كانت \(E_i\) هي القيمة المتوقعة لعدد الخانات الإضافية حتى الوصول لأول تطابق كامل، فلدينا

$$E_d=0,$$

$$E_i=1+\frac1{10}\sum_{x=0}^{9}E_{\delta(i,x)} \qquad (0\le i\lt d),$$

حيث \(\delta(i,x)\) هو انتقال آلة KMP بعد قراءة الرقم \(x\).

3) النظام كله ينهار إلى سلسلة الحدود border chain.

إذا بدأنا من الطول \(d\) واتبعنا وصلات الفشل في دالة البادئة نحصل على

$$d=\ell_0 \gt \ell_1 \gt \ell_2 \gt \cdots \gt \ell_t \gt 0.$$

وهذه هي أطوال الكلمة نفسها وكل حدودها الصحيحة غير الفارغة.

الصيغة المغلقة الدقيقة هي

$$\mathbb E[T_{\mathrm{end}}]=\sum_{j=0}^{t}10^{\ell_j},$$

ومنها

$$g(n)=\sum_{j=0}^{t}10^{\ell_j}-d+1.$$

4) لماذا لا يهم إلا الحدود؟

لو لم يكن هناك أي تداخل ذاتي في النمط لحصلنا فقط على \(10^d\). الحدود تضيف حدوداً أخرى لأن الفشل قد يترك لاحقة قابلة لإعادة الاستخدام، أي لاحقة تساوي بادئة للنمط. هذه الأطوال بالضبط هي التي تسردها سلسلة الحدود.

5) المثال \(n=535\).

هنا \(s=\texttt{535}\) و\(d=3\)، كما أن

$$\pi=[0,0,1].$$

إذن سلسلة الحدود هي

$$3\to1\to0,$$

ومن ثم

$$\mathbb E[T_{\mathrm{end}}]=10^3+10^1=1010,$$

وبالتالي

$$g(535)=1010-3+1=1008.$$

6) النظام الكامل لحالات \(535\).

إذا مثلت الحالات \(0,1,2,3\) السلاسل \(\emptyset,\texttt{5},\texttt{53},\texttt{535}\)، فإننا نحصل على

$$E_3=0,$$

$$E_2=1+\frac9{10}E_0,$$

$$E_1=1+\frac8{10}E_0+\frac1{10}E_1+\frac1{10}E_2,$$

$$E_0=1+\frac9{10}E_0+\frac1{10}E_1.$$

وحل هذا النظام يعطي

$$E_0=1010.$$

إذن صيغة الحدود ليست تبسيطاً تقريبياً، بل هي الشكل المغلق الدقيق للنظام الكامل.

7) مثال سريع بلا حدود غير فارغة.

بالنسبة إلى \(s=\texttt{12}\) لا توجد حدود صحيحة غير فارغة، لذا

$$\mathbb E[T_{\mathrm{end}}]=10^2=100,\qquad g(12)=99.$$

8) لماذا تكون \(g(n)\) دائماً عدداً صحيحاً؟

لأن

$$g(n)=\left(\sum_j10^{\ell_j}\right)-d+1$$

يتكون فقط من قوى صحيحة للعدد \(10\) وتصحيح صحيح.

9) ماذا يفعل الكود عملياً؟

لكل قيمة

$$q=\left\lfloor\frac{10^{16}}{m}\right\rfloor,$$

يقوم بما يلي:

a) يحول \(q\) إلى سلسلة عشرية،

b) يبني دالة البادئة في \(O(d)\)،

c) يسير على السلسلة

$$d,\ \pi[d-1],\ \pi[\pi[d-1]-1],\dots$$

ويجمع الحدود \(10^\ell\)،

d) ثم يطرح \(d-1\).

الخوارزمية

1) حساب \(10^0,\dots,10^{19}\) مسبقاً.

2) لكل \(m=2,\dots,999999\) نحسب \(q=\lfloor10^{16}/m\rfloor\).

3) نبني دالة البادئة لتمثيل \(q\) العشري.

4) نجمع \(10^\ell\) على طول سلسلة الحدود.

5) نطرح \(d-1\) للحصول على \(g(q)\).

6) نجمع القيم في متغير 128-bit.

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

يوجد

$$Q=999998$$

استعلاماً، وكل عدد لا يتجاوز \(16\) خانة عشرية. لذا فالتعقيد الكلي هو

$$O\!\left(\sum d_m\right)=O(16Q),$$

وبذاكرة \(O(d)\) لكل استعلام.

التحقق والنتيجة النهائية

يتحقق البرنامج من

$$g(535)=1008,$$

وكذلك من

$$\sum_{n=2}^{999} g\!\left(\left\lfloor\frac{10^6}{n}\right\rfloor\right)=27280188.$$

والجواب النهائي هو

$$542934735751917735.$$

مراجع إضافية

  1. صفحة المسألة: https://projecteuler.net/problem=316
  2. خوارزمية KMP: https://ar.wikipedia.org/wiki/خوارزمية_كنوث-موريس-برات
  3. Prefix function والحدود: https://cp-algorithms.com/string/prefix-function.html