Problem Summary

We must count positive integer \(N\)-tuples \((x_1,\dots,x_N)\) such that

$$\gcd(x_1,\dots,x_N)\ge G,\qquad \operatorname{lcm}(x_1,\dots,x_N)\le L,$$

and return the result modulo \(101^4\). A direct search is impossible for the actual parameters, so the solution reorganizes each tuple by separating its common gcd from its normalized lcm structure.

Mathematical Approach

Let

$$F(G,L,N)=\#\left\{(x_1,\dots,x_N)\in \mathbb{Z}_{>0}^N:\gcd(x_1,\dots,x_N)\ge G,\ \operatorname{lcm}(x_1,\dots,x_N)\le L\right\}.$$

The key idea is to classify tuples by their common gcd and by the lcm that remains after dividing that gcd out.

Step 1: Normalize by the Common GCD

For any admissible tuple define

$$g=\gcd(x_1,\dots,x_N),\qquad x_i=g\,y_i.$$

Then the normalized tuple satisfies

$$\gcd(y_1,\dots,y_N)=1.$$

Now define

$$m=\operatorname{lcm}(y_1,\dots,y_N).$$

Because lcm scales linearly when every coordinate is multiplied by the same factor, we obtain

$$\operatorname{lcm}(x_1,\dots,x_N)=g\,m.$$

So once the normalized tuple is fixed, the only remaining freedom is the choice of \(g\). The constraints become

$$G\le g\le \left\lfloor\frac{L}{m}\right\rfloor.$$

Hence the number of admissible gcd values for this normalized tuple is

$$w(m)=\left\lfloor\frac{L}{m}\right\rfloor-G+1,$$

and this is positive only when

$$m\le K=\left\lfloor\frac{L}{G}\right\rfloor.$$

Step 2: Define the Normalized Counting Function

Let

$$H_N(m)=\#\left\{(y_1,\dots,y_N)\in \mathbb{Z}_{>0}^N:\gcd(y_1,\dots,y_N)=1,\ \operatorname{lcm}(y_1,\dots,y_N)=m\right\}.$$

This counts exactly the normalized tuples whose lcm is \(m\). Summing over all possible normalized lcm values gives

$$F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor} H_N(m)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right).$$

Therefore the hard part of the problem is reduced to computing \(H_N(m)\) efficiently for every \(m\le K\).

Step 3: Count One Prime Power

Write the prime factorization of \(m\) as

$$m=\prod_{p} p^{e_p}.$$

Fix one prime power \(p^e\parallel m\). For each coordinate \(y_i\), let \(\alpha_i=v_p(y_i)\). Since \(y_i\mid m\), each exponent lies in

$$\alpha_i\in\{0,1,\dots,e\}.$$

The normalized conditions translate into simple conditions on these exponents:

$$\gcd(y_1,\dots,y_N)=1 \iff \min(\alpha_1,\dots,\alpha_N)=0,$$

$$\operatorname{lcm}(y_1,\dots,y_N)=m \iff \max(\alpha_1,\dots,\alpha_N)=e.$$

So for each prime \(p^e\parallel m\), we only need to count exponent vectors in \(\{0,\dots,e\}^N\) whose minimum is \(0\) and whose maximum is \(e\).

Step 4: Inclusion-Exclusion for the Local Factor

The total number of exponent vectors is \((e+1)^N\).

Vectors with no zero exponent use only \(\{1,\dots,e\}\), so there are \(e^N\) of them.

Vectors with no exponent equal to \(e\) also number \(e^N\).

Vectors having neither \(0\) nor \(e\) use only \(\{1,\dots,e-1\}\), so there are \((e-1)^N\).

Therefore inclusion-exclusion gives the local count

$$C_e=(e+1)^N-2e^N+(e-1)^N.$$

This is the number of admissible \(p\)-adic exponent patterns for one prime power. For example, when \(e=1\), we get \(C_1=2^N-2\): all binary exponent vectors except the all-zero and all-one vectors.

Step 5: Reconstruct \(H_N(m)\)

Exponent choices for distinct primes are independent. Once an admissible exponent vector is chosen for each prime \(p^{e_p}\parallel m\), multiplying the prime-power contributions reconstructs one unique normalized tuple \((y_1,\dots,y_N)\).

Hence \(H_N(m)\) is multiplicative and factors as

$$H_N(m)=\prod_{p^{e_p}\parallel m} C_{e_p}=\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right).$$

Step 6: Final Closed Form

Substituting the normalized count into the outer sum yields

$$\boxed{F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor}\left(\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)\right)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)\pmod{101^4}.}$$

This is exactly the formula implemented by the program.

Worked Example: \((G,L,N)=(10,100,2)\)

Here

$$K=\left\lfloor\frac{100}{10}\right\rfloor=10.$$

For \(N=2\), the local factor simplifies to

$$C_e=(e+1)^2-2e^2+(e-1)^2=2.$$

So every prime dividing \(m\) contributes a factor \(2\), and therefore

$$H_2(m)=2^{\omega(m)},$$

where \(\omega(m)\) is the number of distinct prime divisors of \(m\).

Now evaluate the first few terms:

$$\begin{aligned} m=1&:&&H_2(1)=1,\quad w(1)=100-10+1=91,\quad c=91,\\ m=2&:&&H_2(2)=2,\quad w(2)=50-10+1=41,\quad c=82,\\ m=3&:&&H_2(3)=2,\quad w(3)=33-10+1=24,\quad c=48,\\ m=4&:&&H_2(4)=2,\quad w(4)=25-10+1=16,\quad c=32,\\ m=5&:&&H_2(5)=2,\quad w(5)=20-10+1=11,\quad c=22,\\ m=6&:&&H_2(6)=4,\quad w(6)=16-10+1=7,\quad c=28. \end{aligned}$$

The remaining terms are \(10,6,4,4\) for \(m=7,8,9,10\). Therefore

$$91+82+48+32+22+28+10+6+4+4=327,$$

which matches the checkpoint used by the implementation.

How the Code Works

The program first sets \(K=\lfloor L/G\rfloor\) and builds an SPF table (smallest prime factor) up to \(K\). It then precomputes

$$\texttt{local}[e]=C_e=(e+1)^N-2e^N+(e-1)^N \pmod{101^4}$$

using fast modular exponentiation. For each \(m\le K\), the SPF table gives the factorization of \(m\), so the code multiplies the relevant \(\texttt{local}[e]\) values to obtain

$$\texttt{h}[m]=H_N(m)\pmod{101^4}.$$

Finally it accumulates

$$\texttt{h}[m]\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

for all \(1\le m\le K\), always reducing modulo \(101^4\).

Complexity Analysis

Let \(K=\lfloor L/G\rfloor\). Building the SPF sieve costs \(O(K\log\log K)\) time and \(O(K)\) memory. Factoring every \(m\le K\) via the SPF table touches each prime-power exponent once; the total divisor-stripping work has average order \(O(K\log\log K)\). Thus the overall method is near-linear in \(K\) and uses \(O(K)\) memory.

Footnotes and References

  1. Problem page: https://projecteuler.net/problem=350
  2. Least common multiple: Wikipedia — Least common multiple
  3. Greatest common divisor: Wikipedia — Greatest common divisor
  4. Inclusion-exclusion principle: Wikipedia — Inclusion-exclusion principle
  5. Multiplicative function: Wikipedia — Multiplicative function

Problemzusammenfassung

Gesucht ist die Anzahl positiver \(N\)-Tupel \((x_1,\dots,x_N)\) mit

$$\gcd(x_1,\dots,x_N)\ge G,\qquad \operatorname{lcm}(x_1,\dots,x_N)\le L,$$

wobei das Ergebnis modulo \(101^4\) ausgegeben wird. Direkte Enumeration ist für die echten Parameter unmöglich, daher trennt die Lösung den gemeinsamen ggT von der normierten kgV-Struktur.

Mathematischer Ansatz

Definiere

$$F(G,L,N)=\#\left\{(x_1,\dots,x_N)\in \mathbb{Z}_{>0}^N:\gcd(x_1,\dots,x_N)\ge G,\ \operatorname{lcm}(x_1,\dots,x_N)\le L\right\}.$$

Die zentrale Idee ist, jedes Tupel nach seinem gemeinsamen ggT und nach dem kgV des normierten Tupels zu klassifizieren.

Schritt 1: Durch den gemeinsamen ggT normieren

Für ein zulässiges Tupel setze

$$g=\gcd(x_1,\dots,x_N),\qquad x_i=g\,y_i.$$

Dann gilt

$$\gcd(y_1,\dots,y_N)=1.$$

Weiter definieren wir

$$m=\operatorname{lcm}(y_1,\dots,y_N).$$

Da das kgV sich beim Multiplizieren aller Komponenten mit demselben Faktor linear verhält, folgt

$$\operatorname{lcm}(x_1,\dots,x_N)=g\,m.$$

Ist das normierte Tupel fest, bleibt also nur noch die Wahl von \(g\). Die Bedingungen werden zu

$$G\le g\le \left\lfloor\frac{L}{m}\right\rfloor.$$

Damit ist die Anzahl zulässiger ggT-Werte

$$w(m)=\left\lfloor\frac{L}{m}\right\rfloor-G+1,$$

und dieser Ausdruck ist genau dann positiv, wenn

$$m\le K=\left\lfloor\frac{L}{G}\right\rfloor.$$

Schritt 2: Die normierte Zählfunktion

Definiere

$$H_N(m)=\#\left\{(y_1,\dots,y_N)\in \mathbb{Z}_{>0}^N:\gcd(y_1,\dots,y_N)=1,\ \operatorname{lcm}(y_1,\dots,y_N)=m\right\}.$$

Diese Funktion zählt genau die normierten Tupel mit kgV \(m\). Durch Summation über alle möglichen normierten kgV-Werte erhält man

$$F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor} H_N(m)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right).$$

Damit ist das eigentliche Problem auf die effiziente Berechnung von \(H_N(m)\) für alle \(m\le K\) reduziert.

Schritt 3: Zähle eine Primzahlpotenz

Schreibe die Primfaktorzerlegung von \(m\) als

$$m=\prod_{p} p^{e_p}.$$

Fixiere nun eine Primzahlpotenz \(p^e\parallel m\). Für jede Komponente \(y_i\) sei \(\alpha_i=v_p(y_i)\). Da \(y_i\mid m\), gilt

$$\alpha_i\in\{0,1,\dots,e\}.$$

Die normierten Bedingungen lassen sich lokal so formulieren:

$$\gcd(y_1,\dots,y_N)=1 \iff \min(\alpha_1,\dots,\alpha_N)=0,$$

$$\operatorname{lcm}(y_1,\dots,y_N)=m \iff \max(\alpha_1,\dots,\alpha_N)=e.$$

Für jedes \(p^e\parallel m\) müssen wir also Exponentenvektoren in \(\{0,\dots,e\}^N\) zählen, deren Minimum \(0\) und deren Maximum \(e\) ist.

Schritt 4: Inklusion-Exklusion für den lokalen Faktor

Insgesamt gibt es \((e+1)^N\) Exponentenvektoren.

Vektoren ohne Null verwenden nur \(\{1,\dots,e\}\) und sind daher \(e^N\) an der Zahl.

Vektoren ohne Exponent \(e\) gibt es ebenfalls \(e^N\).

Vektoren mit weder \(0\) noch \(e\) verwenden nur \(\{1,\dots,e-1\}\) und sind \((e-1)^N\).

Mit Inklusion-Exklusion erhält man deshalb

$$C_e=(e+1)^N-2e^N+(e-1)^N.$$

Das ist genau die Zahl zulässiger \(p\)-adischer Exponentenmuster für eine Primzahlpotenz. Für \(e=1\) folgt \(C_1=2^N-2\): alle binären Muster außer dem Nullvektor und dem Einsvektor.

Schritt 5: Rekonstruktion von \(H_N(m)\)

Die Exponentenwahl für verschiedene Primzahlen ist unabhängig. Wählt man für jedes \(p^{e_p}\parallel m\) einen zulässigen lokalen Exponentenvektor, so rekonstruiert das Produkt dieser Primzahlpotenzen genau ein normiertes Tupel \((y_1,\dots,y_N)\).

Daher ist \(H_N(m)\) multiplikativ und zerfällt in

$$H_N(m)=\prod_{p^{e_p}\parallel m} C_{e_p}=\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right).$$

Schritt 6: Geschlossene Endformel

Einsetzen in die äußere Summe liefert

$$\boxed{F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor}\left(\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)\right)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)\pmod{101^4}.}$$

Genau diese Formel wird im Programm umgesetzt.

Durchgerechnetes Beispiel: \((G,L,N)=(10,100,2)\)

Hier gilt

$$K=\left\lfloor\frac{100}{10}\right\rfloor=10.$$

Für \(N=2\) vereinfacht sich der lokale Faktor zu

$$C_e=(e+1)^2-2e^2+(e-1)^2=2.$$

Jede Primzahl in \(m\) liefert also den Faktor \(2\), somit

$$H_2(m)=2^{\omega(m)},$$

wobei \(\omega(m)\) die Anzahl verschiedener Primteiler von \(m\) bezeichnet.

Die ersten Terme sind dann

$$\begin{aligned} m=1&:&&H_2(1)=1,\quad w(1)=100-10+1=91,\quad c=91,\\ m=2&:&&H_2(2)=2,\quad w(2)=50-10+1=41,\quad c=82,\\ m=3&:&&H_2(3)=2,\quad w(3)=33-10+1=24,\quad c=48,\\ m=4&:&&H_2(4)=2,\quad w(4)=25-10+1=16,\quad c=32,\\ m=5&:&&H_2(5)=2,\quad w(5)=20-10+1=11,\quad c=22,\\ m=6&:&&H_2(6)=4,\quad w(6)=16-10+1=7,\quad c=28. \end{aligned}$$

Die restlichen Terme für \(m=7,8,9,10\) sind \(10,6,4,4\). Insgesamt also

$$91+82+48+32+22+28+10+6+4+4=327,$$

genau der Kontrollwert aus der Implementierung.

Wie der Code arbeitet

Das Programm setzt zunächst \(K=\lfloor L/G\rfloor\) und baut eine SPF-Tabelle (smallest prime factor) bis \(K\) auf. Danach wird

$$\texttt{local}[e]=C_e=(e+1)^N-2e^N+(e-1)^N \pmod{101^4}$$

per schneller modularer Potenzierung vorab berechnet. Für jedes \(m\le K\) liefert die SPF-Tabelle die Faktorisierung, sodass der Code die passenden \(\texttt{local}[e]\)-Werte multipliziert und damit

$$\texttt{h}[m]=H_N(m)\pmod{101^4}$$

erhält. Anschließend summiert er

$$\texttt{h}[m]\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

für alle \(1\le m\le K\), jeweils modulo \(101^4\).

Komplexitätsanalyse

Mit \(K=\lfloor L/G\rfloor\) kostet das SPF-Sieb \(O(K\log\log K)\) Zeit und \(O(K)\) Speicher. Das Faktorisieren aller \(m\le K\) mittels SPF berührt jede Primzahlpotenz genau einmal; die gesamte Arbeit hat mittlere Größenordnung \(O(K\log\log K)\). Insgesamt ist das Verfahren also nahezu linear in \(K\) und benötigt \(O(K)\) Speicher.

Fußnoten und Quellen

  1. Problemseite: https://projecteuler.net/problem=350
  2. Kleinstes gemeinsames Vielfaches: Wikipedia — Kleinstes gemeinsames Vielfaches
  3. Größter gemeinsamer Teiler: Wikipedia — Größter gemeinsamer Teiler
  4. Inklusions-Exklusions-Prinzip: Wikipedia — Siebformel
  5. Multiplikative Funktion: Wikipedia — Multiplikative Funktion

Problem Özeti

Aranan şey,

$$\gcd(x_1,\dots,x_N)\ge G,\qquad \operatorname{lcm}(x_1,\dots,x_N)\le L,$$

koşullarını sağlayan pozitif tamsayı \(N\)-lilerinin sayısıdır; sonuç \(101^4\) modunda istenir. Gerçek parametrelerde doğrudan tarama imkansız olduğu için çözüm, ortak EBOB'u ayırıp geriye kalan normalize EKOK yapısını sayar.

Matematiksel Yaklaşım

Şunu tanımlayalım:

$$F(G,L,N)=\#\left\{(x_1,\dots,x_N)\in \mathbb{Z}_{>0}^N:\gcd(x_1,\dots,x_N)\ge G,\ \operatorname{lcm}(x_1,\dots,x_N)\le L\right\}.$$

Ana fikir, her diziyi ortak EBOB'una ve bu EBOB çıkarıldıktan sonra kalan normalize EKOK değerine göre sınıflandırmaktır.

Adım 1: Ortak EBOB ile normalize et

Uygun bir dizi için

$$g=\gcd(x_1,\dots,x_N),\qquad x_i=g\,y_i$$

yazalım. Böylece

$$\gcd(y_1,\dots,y_N)=1$$

olur. Ayrıca

$$m=\operatorname{lcm}(y_1,\dots,y_N)$$

tanımını yapalım. Tüm bileşenler aynı katsayıyla çarpıldığında EKOK aynı katsayıyla büyüdüğünden

$$\operatorname{lcm}(x_1,\dots,x_N)=g\,m$$

elde edilir. Yani normalize dizi sabitken geriye sadece \(g\)'nin seçimi kalır. Koşullar

$$G\le g\le \left\lfloor\frac{L}{m}\right\rfloor$$

şeklini alır. Dolayısıyla bu normalize dizi için uygun EBOB sayısı

$$w(m)=\left\lfloor\frac{L}{m}\right\rfloor-G+1$$

olur ve bu ancak

$$m\le K=\left\lfloor\frac{L}{G}\right\rfloor$$

iken pozitiftir.

Adım 2: Normalize sayım fonksiyonunu tanımla

Şimdi

$$H_N(m)=\#\left\{(y_1,\dots,y_N)\in \mathbb{Z}_{>0}^N:\gcd(y_1,\dots,y_N)=1,\ \operatorname{lcm}(y_1,\dots,y_N)=m\right\}$$

tanımını yapalım. Bu fonksiyon, EKOK'u tam olarak \(m\) olan normalize dizilerin sayısını verir. Böylece

$$F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor} H_N(m)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

olur. Yani asıl zor iş, tüm \(m\le K\) için \(H_N(m)\)'yi hızlı hesaplamaktır.

Adım 3: Tek bir asal kuvveti say

\(m\)'nin asal çarpanlara ayrılışı

$$m=\prod_{p} p^{e_p}$$

olsun. Şimdi \(p^e\parallel m\) olan tek bir asal kuvvete odaklanalım. Her \(y_i\) için \(\alpha_i=v_p(y_i)\) olsun. \(y_i\mid m\) olduğundan

$$\alpha_i\in\{0,1,\dots,e\}$$

aralığındadır. Normalize koşullar burada şu anlama gelir:

$$\gcd(y_1,\dots,y_N)=1 \iff \min(\alpha_1,\dots,\alpha_N)=0,$$

$$\operatorname{lcm}(y_1,\dots,y_N)=m \iff \max(\alpha_1,\dots,\alpha_N)=e.$$

Dolayısıyla her \(p^e\parallel m\) için, \(\{0,\dots,e\}^N\) içindeki minimumu \(0\), maksimumu \(e\) olan üs vektörlerini saymamız gerekir.

Adım 4: Yerel katsayı için dahil et-çıkar

Toplam üs vektörü sayısı \((e+1)^N\)'dir.

Hiç \(0\) içermeyen vektörler sadece \(\{1,\dots,e\}\) değerlerini kullanır; sayıları \(e^N\)'dir.

Hiç \(e\) içermeyen vektörlerin sayısı da \(e^N\)'dir.

Ne \(0\) ne \(e\) içerenler yalnızca \(\{1,\dots,e-1\}\) değerlerini kullanır; bunların sayısı \((e-1)^N\)'dir.

Bu yüzden dahil et-çıkar ile yerel sayı

$$C_e=(e+1)^N-2e^N+(e-1)^N$$

olur. Bu, tek bir asal kuvvet için uygun \(p\)-adik üs örüntülerinin sayısıdır. Örneğin \(e=1\) için \(C_1=2^N-2\): tüm ikili vektörler içinden tamamen \(0\) ve tamamen \(1\) olanları çıkarırız.

Adım 5: \(H_N(m)\)'yi yeniden kur

Farklı asalların üs seçimleri birbirinden bağımsızdır. Her \(p^{e_p}\parallel m\) için uygun bir yerel üs vektörü seçildiğinde, bu seçimlerin çarpımı tek bir normalize dizi \((y_1,\dots,y_N)\) üretir.

Bu nedenle \(H_N(m)\) çarpımsaldır ve

$$H_N(m)=\prod_{p^{e_p}\parallel m} C_{e_p}=\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)$$

şeklinde yazılır.

Adım 6: Nihai kapalı form

Böylece dış toplamda yerine koyunca

$$\boxed{F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor}\left(\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)\right)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)\pmod{101^4}.}$$

Programın uyguladığı formül tam olarak budur.

Çözümlü Örnek: \((G,L,N)=(10,100,2)\)

Burada

$$K=\left\lfloor\frac{100}{10}\right\rfloor=10$$

olur. \(N=2\) için yerel katsayı

$$C_e=(e+1)^2-2e^2+(e-1)^2=2$$

şeklinde sadeleşir. Yani \(m\)'yi bölen her farklı asal bir adet \(2\) çarpanı getirir ve

$$H_2(m)=2^{\omega(m)}$$

olur; burada \(\omega(m)\), \(m\)'nin farklı asal bölen sayısıdır.

İlk terimleri yazarsak

$$\begin{aligned} m=1&:&&H_2(1)=1,\quad w(1)=100-10+1=91,\quad c=91,\\ m=2&:&&H_2(2)=2,\quad w(2)=50-10+1=41,\quad c=82,\\ m=3&:&&H_2(3)=2,\quad w(3)=33-10+1=24,\quad c=48,\\ m=4&:&&H_2(4)=2,\quad w(4)=25-10+1=16,\quad c=32,\\ m=5&:&&H_2(5)=2,\quad w(5)=20-10+1=11,\quad c=22,\\ m=6&:&&H_2(6)=4,\quad w(6)=16-10+1=7,\quad c=28. \end{aligned}$$

Kalan \(m=7,8,9,10\) terimleri sırasıyla \(10,6,4,4\) verir. Böylece toplam

$$91+82+48+32+22+28+10+6+4+4=327$$

olur; bu da implementasyondaki kontrol değeriyle aynıdır.

Kodda bunun karşılığı

Program önce \(K=\lfloor L/G\rfloor\) değerini alır ve \(K\)'ye kadar en küçük asal bölen tablosunu (spf) kurar. Ardından hızlı modüler üs alma ile

$$\texttt{local}[e]=C_e=(e+1)^N-2e^N+(e-1)^N \pmod{101^4}$$

değerleri önceden hesaplanır. Her \(m\le K\) için spf sayesinde çarpanlara ayrıştırma yapılır ve ilgili \(\texttt{local}[e]\) değerleri çarpılarak

$$\texttt{h}[m]=H_N(m)\pmod{101^4}$$

elde edilir. Son adımda tüm \(1\le m\le K\) için

$$\texttt{h}[m]\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

toplanır ve her adımda \(101^4\) moduna göre indirgeme yapılır.

Karmaşıklık Analizi

\(K=\lfloor L/G\rfloor\) olsun. SPF süzgeci \(O(K\log\log K)\) zaman ve \(O(K)\) bellek gerektirir. Tüm \(m\le K\) sayılarının SPF ile çarpanlanması sırasında her asal kuvvet üssü bir kez işlenir; toplam iş yükü ortalama mertebede \(O(K\log\log K)\)'dir. Sonuç olarak yöntem \(K\)'ye göre yaklaşık lineer çalışır ve \(O(K)\) bellek kullanır.

Dipnotlar ve Kaynakça

  1. Problem sayfası: https://projecteuler.net/problem=350
  2. En küçük ortak kat: Wikipedia — En küçük ortak kat
  3. En büyük ortak bölen: Wikipedia — En büyük ortak bölen
  4. Dahil etme-hariç tutma ilkesi: Wikipedia — İçerme-dışlama prensibi
  5. Çarpımsal fonksiyon: Wikipedia — Çarpımsal fonksiyon

Resumen del Problema

Debemos contar las \(N\)-tuplas de enteros positivos \((x_1,\dots,x_N)\) que satisfacen

$$\gcd(x_1,\dots,x_N)\ge G,\qquad \operatorname{lcm}(x_1,\dots,x_N)\le L,$$

y devolver el resultado módulo \(101^4\). Una búsqueda directa es inviable para los parámetros reales, así que la solución separa el factor común máximo y la estructura normalizada del mcm.

Enfoque Matemático

Definimos

$$F(G,L,N)=\#\left\{(x_1,\dots,x_N)\in \mathbb{Z}_{>0}^N:\gcd(x_1,\dots,x_N)\ge G,\ \operatorname{lcm}(x_1,\dots,x_N)\le L\right\}.$$

La idea clave es clasificar cada tupla por su mcd común y por el mcm que queda después de dividir ese mcd.

Paso 1: Normalizar por el mcd común

Para una tupla válida, escribimos

$$g=\gcd(x_1,\dots,x_N),\qquad x_i=g\,y_i.$$

Entonces

$$\gcd(y_1,\dots,y_N)=1.$$

Además definimos

$$m=\operatorname{lcm}(y_1,\dots,y_N).$$

Como el mcm escala linealmente al multiplicar todas las coordenadas por el mismo factor, tenemos

$$\operatorname{lcm}(x_1,\dots,x_N)=g\,m.$$

Así, fijada la tupla normalizada, solo queda elegir \(g\). Las restricciones pasan a ser

$$G\le g\le \left\lfloor\frac{L}{m}\right\rfloor.$$

Por tanto, el número de valores posibles de \(g\) es

$$w(m)=\left\lfloor\frac{L}{m}\right\rfloor-G+1,$$

y esto solo es positivo cuando

$$m\le K=\left\lfloor\frac{L}{G}\right\rfloor.$$

Paso 2: Definir la función de conteo normalizada

Sea

$$H_N(m)=\#\left\{(y_1,\dots,y_N)\in \mathbb{Z}_{>0}^N:\gcd(y_1,\dots,y_N)=1,\ \operatorname{lcm}(y_1,\dots,y_N)=m\right\}.$$

Esta función cuenta exactamente las tuplas normalizadas cuyo mcm es \(m\). Entonces

$$F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor} H_N(m)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right).$$

El problema se reduce así a calcular \(H_N(m)\) de forma eficiente para todo \(m\le K\).

Paso 3: Contar una sola potencia prima

Escribimos la factorización prima de \(m\) como

$$m=\prod_{p} p^{e_p}.$$

Fijemos una potencia prima \(p^e\parallel m\). Para cada coordenada \(y_i\), sea \(\alpha_i=v_p(y_i)\). Como \(y_i\mid m\), se cumple

$$\alpha_i\in\{0,1,\dots,e\}.$$

Las condiciones normalizadas se traducen localmente en

$$\gcd(y_1,\dots,y_N)=1 \iff \min(\alpha_1,\dots,\alpha_N)=0,$$

$$\operatorname{lcm}(y_1,\dots,y_N)=m \iff \max(\alpha_1,\dots,\alpha_N)=e.$$

Por tanto, para cada \(p^e\parallel m\) solo necesitamos contar los vectores de exponentes en \(\{0,\dots,e\}^N\) cuyo mínimo sea \(0\) y cuyo máximo sea \(e\).

Paso 4: Inclusión-exclusión para el factor local

El número total de vectores de exponentes es \((e+1)^N\).

Los vectores sin ningún \(0\) usan solo \(\{1,\dots,e\}\), así que son \(e^N\).

Los vectores sin ningún exponente igual a \(e\) también son \(e^N\).

Los vectores que no contienen ni \(0\) ni \(e\) usan solo \(\{1,\dots,e-1\}\), luego son \((e-1)^N\).

Por inclusión-exclusión obtenemos

$$C_e=(e+1)^N-2e^N+(e-1)^N.$$

Ese es el número de patrones \(p\)-ádicos válidos para una potencia prima. Por ejemplo, si \(e=1\), entonces \(C_1=2^N-2\): todos los vectores binarios salvo el de todo ceros y el de todo unos.

Paso 5: Reconstruir \(H_N(m)\)

Las elecciones de exponentes para primos distintos son independientes. Si elegimos un vector local válido para cada \(p^{e_p}\parallel m\), el producto de esas contribuciones reconstruye una única tupla normalizada \((y_1,\dots,y_N)\).

Por ello, \(H_N(m)\) es multiplicativa y se factoriza como

$$H_N(m)=\prod_{p^{e_p}\parallel m} C_{e_p}=\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right).$$

Paso 6: Fórmula final cerrada

Sustituyendo en la suma exterior, resulta

$$\boxed{F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor}\left(\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)\right)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)\pmod{101^4}.}$$

Esa es exactamente la fórmula utilizada por el programa.

Ejemplo trabajado: \((G,L,N)=(10,100,2)\)

Aquí

$$K=\left\lfloor\frac{100}{10}\right\rfloor=10.$$

Para \(N=2\), el factor local se simplifica a

$$C_e=(e+1)^2-2e^2+(e-1)^2=2.$$

Cada primo distinto que divide a \(m\) aporta entonces un factor \(2\), y por tanto

$$H_2(m)=2^{\omega(m)},$$

donde \(\omega(m)\) es el número de divisores primos distintos de \(m\).

Los primeros términos son

$$\begin{aligned} m=1&:&&H_2(1)=1,\quad w(1)=100-10+1=91,\quad c=91,\\ m=2&:&&H_2(2)=2,\quad w(2)=50-10+1=41,\quad c=82,\\ m=3&:&&H_2(3)=2,\quad w(3)=33-10+1=24,\quad c=48,\\ m=4&:&&H_2(4)=2,\quad w(4)=25-10+1=16,\quad c=32,\\ m=5&:&&H_2(5)=2,\quad w(5)=20-10+1=11,\quad c=22,\\ m=6&:&&H_2(6)=4,\quad w(6)=16-10+1=7,\quad c=28. \end{aligned}$$

Los términos restantes para \(m=7,8,9,10\) son \(10,6,4,4\). Por tanto

$$91+82+48+32+22+28+10+6+4+4=327,$$

que coincide con el valor de comprobación de la implementación.

Cómo funciona el código

El programa fija \(K=\lfloor L/G\rfloor\) y construye una tabla SPF (smallest prime factor) hasta \(K\). Luego precalcula

$$\texttt{local}[e]=C_e=(e+1)^N-2e^N+(e-1)^N \pmod{101^4}$$

mediante exponenciación modular rápida. Para cada \(m\le K\), la tabla SPF entrega la factorización de \(m\), y el código multiplica los valores \(\texttt{local}[e]\) correspondientes para obtener

$$\texttt{h}[m]=H_N(m)\pmod{101^4}.$$

Finalmente suma

$$\texttt{h}[m]\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

para todo \(1\le m\le K\), siempre reduciendo módulo \(101^4\).

Complejidad

Sea \(K=\lfloor L/G\rfloor\). Construir la criba SPF cuesta \(O(K\log\log K)\) tiempo y \(O(K)\) memoria. Factorizar todos los \(m\le K\) usando esa tabla toca cada exponente primo una vez; el trabajo total tiene orden medio \(O(K\log\log K)\). En conjunto, el método es casi lineal en \(K\) y usa \(O(K)\) memoria.

Notas y Referencias

  1. Página del problema: https://projecteuler.net/problem=350
  2. Mínimo común múltiplo: Wikipedia — Mínimo común múltiplo
  3. Máximo común divisor: Wikipedia — Máximo común divisor
  4. Principio de inclusión-exclusión: Wikipedia — Principio de inclusión-exclusión
  5. Función multiplicativa: Wikipedia — Función multiplicativa

问题概述

我们要求的是满足

$$\gcd(x_1,\dots,x_N)\ge G,\qquad \operatorname{lcm}(x_1,\dots,x_N)\le L,$$

的正整数 \(N\) 元组 \((x_1,\dots,x_N)\) 的个数,并对 \(101^4\) 取模。真实参数极大,不能暴力枚举,所以解法要把“公共 gcd”与“归一化后的 lcm 结构”拆开来数。

数学方法

定义

$$F(G,L,N)=\#\left\{(x_1,\dots,x_N)\in \mathbb{Z}_{>0}^N:\gcd(x_1,\dots,x_N)\ge G,\ \operatorname{lcm}(x_1,\dots,x_N)\le L\right\}.$$

核心思想是先提取所有坐标的公共 gcd,再统计去掉这个 gcd 之后剩下的标准化元组。

步骤 1:把公共 gcd 提出来

对任意合法元组,设

$$g=\gcd(x_1,\dots,x_N),\qquad x_i=g\,y_i.$$

于是有

$$\gcd(y_1,\dots,y_N)=1.$$

再定义

$$m=\operatorname{lcm}(y_1,\dots,y_N).$$

因为所有坐标同时乘以 \(g\) 时,lcm 也会同时乘以 \(g\),所以

$$\operatorname{lcm}(x_1,\dots,x_N)=g\,m.$$

这样一来,在标准化元组固定之后,剩下唯一的自由度就是 \(g\)。条件变成

$$G\le g\le \left\lfloor\frac{L}{m}\right\rfloor.$$

因此,对一个给定的标准化元组,其可选的 \(g\) 个数是

$$w(m)=\left\lfloor\frac{L}{m}\right\rfloor-G+1,$$

并且只有当

$$m\le K=\left\lfloor\frac{L}{G}\right\rfloor$$

时这个数量才是正的。

步骤 2:定义标准化计数函数

定义

$$H_N(m)=\#\left\{(y_1,\dots,y_N)\in \mathbb{Z}_{>0}^N:\gcd(y_1,\dots,y_N)=1,\ \operatorname{lcm}(y_1,\dots,y_N)=m\right\}.$$

它表示 lcm 恰好等于 \(m\) 的标准化元组个数。于是

$$F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor} H_N(m)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right).$$

因此真正需要高效计算的是所有 \(m\le K\) 的 \(H_N(m)\)。

步骤 3:先看单个素数幂

把 \(m\) 分解成

$$m=\prod_{p} p^{e_p}.$$

固定其中一个素数幂 \(p^e\parallel m\)。对每个坐标 \(y_i\),令 \(\alpha_i=v_p(y_i)\)。由于 \(y_i\mid m\),所以

$$\alpha_i\in\{0,1,\dots,e\}.$$

标准化条件在这个素数上等价于

$$\gcd(y_1,\dots,y_N)=1 \iff \min(\alpha_1,\dots,\alpha_N)=0,$$

$$\operatorname{lcm}(y_1,\dots,y_N)=m \iff \max(\alpha_1,\dots,\alpha_N)=e.$$

所以对每个 \(p^e\parallel m\),我们只需统计 \(\{0,\dots,e\}^N\) 中最小值为 \(0\)、最大值为 \(e\) 的指数向量。

步骤 4:局部因子用容斥来数

指数向量总数是 \((e+1)^N\)。

没有 \(0\) 的向量只能从 \(\{1,\dots,e\}\) 中取值,所以有 \(e^N\) 个。

没有 \(e\) 的向量同样有 \(e^N\) 个。

既没有 \(0\) 又没有 \(e\) 的向量只能从 \(\{1,\dots,e-1\}\) 中取值,所以有 \((e-1)^N\) 个。

因此由容斥原理可得局部计数

$$C_e=(e+1)^N-2e^N+(e-1)^N.$$

这就是一个素数幂对应的合法 \(p\)-进指数模式个数。例如 \(e=1\) 时,\(C_1=2^N-2\),即所有二进制向量里去掉全 \(0\) 和全 \(1\) 两种。

步骤 5:恢复 \(H_N(m)\)

不同素数的指数选择彼此独立。对每个 \(p^{e_p}\parallel m\) 选定一个合法的局部指数向量之后,把各个素数幂贡献乘起来,就能唯一重建一个标准化元组 \((y_1,\dots,y_N)\)。

因此 \(H_N(m)\) 是乘法性的,并且

$$H_N(m)=\prod_{p^{e_p}\parallel m} C_{e_p}=\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right).$$

步骤 6:最终闭式

代回外层求和后得到

$$\boxed{F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor}\left(\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)\right)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)\pmod{101^4}.}$$

程序实现的就是这条公式。

示例:\((G,L,N)=(10,100,2)\)

此时

$$K=\left\lfloor\frac{100}{10}\right\rfloor=10.$$

当 \(N=2\) 时,局部因子化简为

$$C_e=(e+1)^2-2e^2+(e-1)^2=2.$$

也就是说,\(m\) 的每个不同素因子都会贡献一个 \(2\),所以

$$H_2(m)=2^{\omega(m)},$$

其中 \(\omega(m)\) 表示 \(m\) 的不同素因子个数。

前几项为

$$\begin{aligned} m=1&:&&H_2(1)=1,\quad w(1)=100-10+1=91,\quad c=91,\\ m=2&:&&H_2(2)=2,\quad w(2)=50-10+1=41,\quad c=82,\\ m=3&:&&H_2(3)=2,\quad w(3)=33-10+1=24,\quad c=48,\\ m=4&:&&H_2(4)=2,\quad w(4)=25-10+1=16,\quad c=32,\\ m=5&:&&H_2(5)=2,\quad w(5)=20-10+1=11,\quad c=22,\\ m=6&:&&H_2(6)=4,\quad w(6)=16-10+1=7,\quad c=28. \end{aligned}$$

剩下 \(m=7,8,9,10\) 的贡献分别是 \(10,6,4,4\)。因此

$$91+82+48+32+22+28+10+6+4+4=327,$$

与代码中的校验值完全一致。

代码如何对应这个公式

程序先设 \(K=\lfloor L/G\rfloor\),并建立到 \(K\) 为止的最小素因子表(SPF)。随后用快速模幂预处理

$$\texttt{local}[e]=C_e=(e+1)^N-2e^N+(e-1)^N \pmod{101^4}.$$

对于每个 \(m\le K\),SPF 表给出其分解,代码把对应的 \(\texttt{local}[e]\) 相乘,得到

$$\texttt{h}[m]=H_N(m)\pmod{101^4}.$$

最后把所有

$$\texttt{h}[m]\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

累加起来,并始终对 \(101^4\) 取模。

复杂度分析

设 \(K=\lfloor L/G\rfloor\)。建立 SPF 筛需要 \(O(K\log\log K)\) 时间和 \(O(K)\) 空间。随后对所有 \(m\le K\) 的 SPF 分解会逐个处理素数幂指数,总工作量的平均数量级为 \(O(K\log\log K)\)。因此整体方法关于 \(K\) 近似线性,空间复杂度为 \(O(K)\)。

参考资料

  1. 题目页面: https://projecteuler.net/problem=350
  2. 最小公倍数: Wikipedia — 最小公倍数
  3. 最大公约数: Wikipedia — 最大公约数
  4. 容斥原理: Wikipedia — 容斥原理
  5. 乘法函数: Wikipedia — 乘法函数

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

Нужно посчитать число \(N\)-кортежей положительных целых чисел \((x_1,\dots,x_N)\), для которых

$$\gcd(x_1,\dots,x_N)\ge G,\qquad \operatorname{lcm}(x_1,\dots,x_N)\le L,$$

и вернуть ответ по модулю \(101^4\). Для реальных параметров полный перебор невозможен, поэтому решение отделяет общий НОД от нормализованной структуры НОК.

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

Обозначим

$$F(G,L,N)=\#\left\{(x_1,\dots,x_N)\in \mathbb{Z}_{>0}^N:\gcd(x_1,\dots,x_N)\ge G,\ \operatorname{lcm}(x_1,\dots,x_N)\le L\right\}.$$

Ключевая идея состоит в том, чтобы классифицировать кортежи по общему НОД и по НОК, остающемуся после деления на этот НОД.

Шаг 1: Нормализация по общему НОД

Для любого допустимого кортежа положим

$$g=\gcd(x_1,\dots,x_N),\qquad x_i=g\,y_i.$$

Тогда

$$\gcd(y_1,\dots,y_N)=1.$$

Далее введем

$$m=\operatorname{lcm}(y_1,\dots,y_N).$$

Так как НОК масштабируется тем же множителем при умножении всех координат на \(g\), получаем

$$\operatorname{lcm}(x_1,\dots,x_N)=g\,m.$$

Значит, после фиксации нормализованного кортежа остается выбрать только \(g\). Ограничения становятся такими:

$$G\le g\le \left\lfloor\frac{L}{m}\right\rfloor.$$

Число допустимых значений \(g\) равно

$$w(m)=\left\lfloor\frac{L}{m}\right\rfloor-G+1,$$

и оно положительно лишь при

$$m\le K=\left\lfloor\frac{L}{G}\right\rfloor.$$

Шаг 2: Нормализованная функция подсчета

Определим

$$H_N(m)=\#\left\{(y_1,\dots,y_N)\in \mathbb{Z}_{>0}^N:\gcd(y_1,\dots,y_N)=1,\ \operatorname{lcm}(y_1,\dots,y_N)=m\right\}.$$

Эта функция считает ровно те нормализованные кортежи, у которых НОК равен \(m\). Тогда

$$F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor} H_N(m)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right).$$

Таким образом, основная часть задачи сводится к быстрому вычислению \(H_N(m)\) для всех \(m\le K\).

Шаг 3: Подсчет для одной степени простого

Разложим \(m\) на простые множители:

$$m=\prod_{p} p^{e_p}.$$

Зафиксируем одну степень простого \(p^e\parallel m\). Для каждой координаты \(y_i\) обозначим \(\alpha_i=v_p(y_i)\). Поскольку \(y_i\mid m\), имеем

$$\alpha_i\in\{0,1,\dots,e\}.$$

Тогда нормализованные условия локально переписываются так:

$$\gcd(y_1,\dots,y_N)=1 \iff \min(\alpha_1,\dots,\alpha_N)=0,$$

$$\operatorname{lcm}(y_1,\dots,y_N)=m \iff \max(\alpha_1,\dots,\alpha_N)=e.$$

Итак, для каждого \(p^e\parallel m\) нужно посчитать число векторов из \(\{0,\dots,e\}^N\), у которых минимум равен \(0\), а максимум равен \(e\).

Шаг 4: Локальный множитель через включение-исключение

Всего существует \((e+1)^N\) векторов показателей.

Векторов без нуля, использующих только \(\{1,\dots,e\}\), ровно \(e^N\).

Векторов без значения \(e\) также \(e^N\).

Векторов без \(0\) и без \(e\), использующих только \(\{1,\dots,e-1\}\), ровно \((e-1)^N\).

Следовательно, по принципу включения-исключения

$$C_e=(e+1)^N-2e^N+(e-1)^N.$$

Это число допустимых \(p\)-адических шаблонов для одной степени простого. Например, при \(e=1\) получаем \(C_1=2^N-2\): все двоичные векторы, кроме полностью нулевого и полностью единичного.

Шаг 5: Восстановление \(H_N(m)\)

Выборы показателей для разных простых независимы. Если для каждого \(p^{e_p}\parallel m\) выбрать допустимый локальный вектор показателей, то произведение вкладов по простым однозначно восстанавливает нормализованный кортеж \((y_1,\dots,y_N)\).

Поэтому \(H_N(m)\) мультипликативна и раскладывается в произведение

$$H_N(m)=\prod_{p^{e_p}\parallel m} C_{e_p}=\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right).$$

Шаг 6: Итоговая формула

Подставляя это в внешнюю сумму, получаем

$$\boxed{F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor}\left(\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)\right)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)\pmod{101^4}.}$$

Именно эту формулу и реализует программа.

Разобранный пример: \((G,L,N)=(10,100,2)\)

Здесь

$$K=\left\lfloor\frac{100}{10}\right\rfloor=10.$$

При \(N=2\) локальный множитель упрощается:

$$C_e=(e+1)^2-2e^2+(e-1)^2=2.$$

Следовательно, каждый различный простой делитель \(m\) дает множитель \(2\), и потому

$$H_2(m)=2^{\omega(m)},$$

где \(\omega(m)\) обозначает число различных простых делителей \(m\).

Первые слагаемые:

$$\begin{aligned} m=1&:&&H_2(1)=1,\quad w(1)=100-10+1=91,\quad c=91,\\ m=2&:&&H_2(2)=2,\quad w(2)=50-10+1=41,\quad c=82,\\ m=3&:&&H_2(3)=2,\quad w(3)=33-10+1=24,\quad c=48,\\ m=4&:&&H_2(4)=2,\quad w(4)=25-10+1=16,\quad c=32,\\ m=5&:&&H_2(5)=2,\quad w(5)=20-10+1=11,\quad c=22,\\ m=6&:&&H_2(6)=4,\quad w(6)=16-10+1=7,\quad c=28. \end{aligned}$$

Оставшиеся слагаемые для \(m=7,8,9,10\) равны \(10,6,4,4\). Значит,

$$91+82+48+32+22+28+10+6+4+4=327,$$

что совпадает с контрольным значением в реализации.

Как это отражено в коде

Сначала программа вычисляет \(K=\lfloor L/G\rfloor\) и строит таблицу SPF (наименьший простой делитель) до \(K\). Затем с помощью быстрого возведения в степень по модулю заранее считаются значения

$$\texttt{local}[e]=C_e=(e+1)^N-2e^N+(e-1)^N \pmod{101^4}.$$

Для каждого \(m\le K\) таблица SPF дает его разложение, после чего код перемножает соответствующие \(\texttt{local}[e]\) и получает

$$\texttt{h}[m]=H_N(m)\pmod{101^4}.$$

Далее суммируется

$$\texttt{h}[m]\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

для всех \(1\le m\le K\), причем после каждого шага берется остаток по модулю \(101^4\).

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

Пусть \(K=\lfloor L/G\rfloor\). Построение SPF-решета требует \(O(K\log\log K)\) времени и \(O(K)\) памяти. Факторизация всех \(m\le K\) с помощью SPF проходит по показателям простых степеней; суммарная трудоемкость имеет средний порядок \(O(K\log\log K)\). В итоге метод работает почти линейно по \(K\) и использует \(O(K)\) памяти.

Ссылки и литература

  1. Страница задачи: https://projecteuler.net/problem=350
  2. Наименьшее общее кратное: Wikipedia — НОК
  3. Наибольший общий делитель: Wikipedia — НОД
  4. Принцип включения-исключения: Wikipedia — Включение-исключение
  5. Мультипликативная функция: Wikipedia — Мультипликативная функция

ملخص المسألة

نريد عدّ جميع المتتاليات \((x_1,\dots,x_N)\) من الأعداد الصحيحة الموجبة التي تحقق

$$\gcd(x_1,\dots,x_N)\ge G,\qquad \operatorname{lcm}(x_1,\dots,x_N)\le L,$$

ثم نأخذ الجواب بترديد \(101^4\). وبما أن التعداد المباشر مستحيل عمليًا للقيم الفعلية، فإن الحل يفصل بين القاسم المشترك الأكبر العام وبين بنية المضاعف المشترك الأصغر بعد التطبيع.

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

لنعرّف

$$F(G,L,N)=\#\left\{(x_1,\dots,x_N)\in \mathbb{Z}_{>0}^N:\gcd(x_1,\dots,x_N)\ge G,\ \operatorname{lcm}(x_1,\dots,x_N)\le L\right\}.$$

الفكرة الأساسية هي تصنيف كل متتالية بحسب القاسم المشترك الأكبر لها، ثم بحسب قيمة المضاعف المشترك الأصغر بعد قسمة هذا العامل المشترك.

الخطوة 1: التطبيع بإخراج القاسم المشترك الأكبر

لكل متتالية صالحة نكتب

$$g=\gcd(x_1,\dots,x_N),\qquad x_i=g\,y_i.$$

عندئذٍ يصبح

$$\gcd(y_1,\dots,y_N)=1.$$

ثم نعرّف

$$m=\operatorname{lcm}(y_1,\dots,y_N).$$

وبما أن المضاعف المشترك الأصغر يتمدد بنفس العامل عند ضرب جميع الحدود في \(g\)، فإن

$$\operatorname{lcm}(x_1,\dots,x_N)=g\,m.$$

إذًا بعد تثبيت المتتالية المطبّعة لا يبقى إلا اختيار \(g\). وتتحول الشروط إلى

$$G\le g\le \left\lfloor\frac{L}{m}\right\rfloor.$$

ومن ثم يكون عدد قيم \(g\) الممكنة هو

$$w(m)=\left\lfloor\frac{L}{m}\right\rfloor-G+1,$$

وهذا لا يكون موجبًا إلا إذا

$$m\le K=\left\lfloor\frac{L}{G}\right\rfloor.$$

الخطوة 2: تعريف دالة العدّ المطبّعة

نعرّف

$$H_N(m)=\#\left\{(y_1,\dots,y_N)\in \mathbb{Z}_{>0}^N:\gcd(y_1,\dots,y_N)=1,\ \operatorname{lcm}(y_1,\dots,y_N)=m\right\}.$$

هذه الدالة تعدّ جميع المتتاليات المطبّعة التي يكون فيها المضاعف المشترك الأصغر مساويًا تمامًا لـ \(m\). لذلك نحصل على

$$F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor} H_N(m)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right).$$

إذن الجزء الأصعب من المسألة هو إيجاد \(H_N(m)\) بسرعة لكل \(m\le K\).

الخطوة 3: عدّ قوة أولية واحدة

لنكتب تحليل \(m\) إلى عوامل أولية على الصورة

$$m=\prod_{p} p^{e_p}.$$

ثبّت الآن عاملًا أوليًا واحدًا \(p^e\parallel m\). ولكل حد \(y_i\)، لنرمز إلى أس \(p\) فيه بالرمز \(\alpha_i=v_p(y_i)\). بما أن \(y_i\mid m\)، فلدينا

$$\alpha_i\in\{0,1,\dots,e\}.$$

وعند هذا العامل الأولي فقط تصبح شروط التطبيع مكافئة لما يلي:

$$\gcd(y_1,\dots,y_N)=1 \iff \min(\alpha_1,\dots,\alpha_N)=0,$$

$$\operatorname{lcm}(y_1,\dots,y_N)=m \iff \max(\alpha_1,\dots,\alpha_N)=e.$$

إذن المطلوب محليًا هو عدّ متجهات الأسس في \(\{0,\dots,e\}^N\) التي يكون أصغر عنصر فيها \(0\) وأكبر عنصر فيها \(e\).

الخطوة 4: العامل المحلي باستخدام الاشتمال والاستبعاد

عدد جميع متجهات الأسس هو \((e+1)^N\).

أما المتجهات التي لا تحتوي على \(0\) فتأخذ قيمها فقط من \(\{1,\dots,e\}\)، وعددها \(e^N\).

والمتجهات التي لا تحتوي على \(e\) عددها أيضًا \(e^N\).

والمتجهات التي لا تحتوي على \(0\) ولا على \(e\) تستخدم فقط \(\{1,\dots,e-1\}\)، وعددها \((e-1)^N\).

إذًا يعطي مبدأ الاشتمال والاستبعاد

$$C_e=(e+1)^N-2e^N+(e-1)^N.$$

وهذا هو عدد الأنماط الصحيحة للأسس \(p\)-العددية لقوة أولية واحدة. فعندما \(e=1\) مثلًا نحصل على \(C_1=2^N-2\)، أي جميع المتجهات الثنائية ما عدا المتجه الصفري الكامل والمتجه الأحادي الكامل.

الخطوة 5: إعادة بناء \(H_N(m)\)

اختيارات الأسس الخاصة بالأعداد الأولية المختلفة مستقلة عن بعضها. فإذا اخترنا متجهًا محليًا صالحًا لكل \(p^{e_p}\parallel m\)، فإن ضرب هذه المساهمات يعيد بناء متتالية مطبّعة وحيدة \((y_1,\dots,y_N)\).

لذلك فإن \(H_N(m)\) دالة ضربية وتتفكك على الصورة

$$H_N(m)=\prod_{p^{e_p}\parallel m} C_{e_p}=\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right).$$

الخطوة 6: الصيغة النهائية المغلقة

وبالتعويض في المجموع الخارجي نحصل على

$$\boxed{F(G,L,N)=\sum_{m=1}^{\lfloor L/G\rfloor}\left(\prod_{p^{e_p}\parallel m}\left((e_p+1)^N-2e_p^N+(e_p-1)^N\right)\right)\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)\pmod{101^4}.}$$

وهذه هي الصيغة التي يطبقها الكود مباشرة.

مثال محلول: \((G,L,N)=(10,100,2)\)

في هذه الحالة

$$K=\left\lfloor\frac{100}{10}\right\rfloor=10.$$

وعندما \(N=2\) يتبسط العامل المحلي إلى

$$C_e=(e+1)^2-2e^2+(e-1)^2=2.$$

أي أن كل عدد أولي مختلف يقسم \(m\) يضيف عاملًا مقداره \(2\)، ومن ثم

$$H_2(m)=2^{\omega(m)},$$

حيث \(\omega(m)\) هو عدد القواسم الأولية المختلفة لـ \(m\).

وبذلك تكون الحدود الأولى

$$\begin{aligned} m=1&:&&H_2(1)=1,\quad w(1)=100-10+1=91,\quad c=91,\\ m=2&:&&H_2(2)=2,\quad w(2)=50-10+1=41,\quad c=82,\\ m=3&:&&H_2(3)=2,\quad w(3)=33-10+1=24,\quad c=48,\\ m=4&:&&H_2(4)=2,\quad w(4)=25-10+1=16,\quad c=32,\\ m=5&:&&H_2(5)=2,\quad w(5)=20-10+1=11,\quad c=22,\\ m=6&:&&H_2(6)=4,\quad w(6)=16-10+1=7,\quad c=28. \end{aligned}$$

أما القيم الباقية لـ \(m=7,8,9,10\) فتعطي \(10,6,4,4\). إذًا

$$91+82+48+32+22+28+10+6+4+4=327,$$

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

كيف يظهر ذلك في الكود

يحسب البرنامج أولًا \(K=\lfloor L/G\rfloor\)، ثم يبني جدول أصغر عامل أولي (spf) حتى \(K\). بعد ذلك يسبق حساب

$$\texttt{local}[e]=C_e=(e+1)^N-2e^N+(e-1)^N \pmod{101^4}$$

باستخدام الأس السريع بترديد ثابت. ولكل \(m\le K\) يعطي جدول spf تحليل \(m\)، فيضرب الكود قيم \(\texttt{local}[e]\) المناسبة ليحصل على

$$\texttt{h}[m]=H_N(m)\pmod{101^4}.$$

وفي النهاية يجمع

$$\texttt{h}[m]\left(\left\lfloor\frac{L}{m}\right\rfloor-G+1\right)$$

لكل \(1\le m\le K\)، مع الاختزال دائمًا بترديد \(101^4\).

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

إذا وضعنا \(K=\lfloor L/G\rfloor\)، فإن بناء غربال SPF يحتاج إلى زمن \(O(K\log\log K)\) وذاكرة \(O(K)\). أما تحليل جميع الأعداد \(m\le K\) باستخدام هذا الجدول فيمر على أسس القوى الأولية مرة واحدة لكل عامل، ويكون مجموع العمل ذا رتبة وسطية \(O(K\log\log K)\). لذلك فالخوارزمية شبه خطية في \(K\) وتستخدم \(O(K)\) من الذاكرة.

مراجع

  1. صفحة المسألة: https://projecteuler.net/problem=350
  2. المضاعف المشترك الأصغر: Wikipedia — المضاعف المشترك الأصغر
  3. القاسم المشترك الأكبر: Wikipedia — القاسم المشترك الأكبر
  4. مبدأ الاشتمال والاستبعاد: Wikipedia — الاشتمال والاستبعاد
  5. الدالة الضربية: Wikipedia — الدالة الضربية