Let
$$T(r)=\#\left\{(x_1,x_2,x_3,x_4)\in\mathbb Z^4: x_1^2+x_2^2+x_3^2+x_4^2\le r^2\right\}.$$
The problem asks for this lattice-point count in four dimensions when \(r=10^8\), with the final value reduced modulo \(10^9+7\). A direct enumeration of all integer quadruples is hopeless, so the solution converts the geometry into a divisor sum that can be evaluated in about \(O(\sqrt{r^2})\) time.
The key observation is that the hyperball can be counted shell by shell according to the squared distance from the origin.
Set \(N=r^2\). For each integer \(n\ge 0\), let \(r_4(n)\) be the number of integer quadruples satisfying
$$x_1^2+x_2^2+x_3^2+x_4^2=n.$$
Every lattice point inside the ball has some squared radius \(n\) with \(0\le n\le N\), so
$$T(r)=\sum_{n=0}^{N} r_4(n).$$
This removes the geometric viewpoint and replaces it with a summation problem.
For \(n>0\), Jacobi's theorem gives
$$r_4(n)=8\sum_{\substack{d\mid n\\4\nmid d}} d,$$
and of course \(r_4(0)=1\). Substituting this into the previous identity yields
$$T(r)=1+8\sum_{n=1}^{N}\sum_{\substack{d\mid n\\4\nmid d}} d.$$
Now interchange the order of summation. A fixed divisor \(d\) contributes once for each multiple of \(d\) up to \(N\), so it appears exactly \(\left\lfloor N/d\right\rfloor\) times. Therefore
$$T(r)=1+8\sum_{\substack{d\le N\\4\nmid d}} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Introduce the summatory function
$$S(N)=\sum_{d=1}^{N} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Then the terms with \(4\nmid d\) are obtained by subtracting the terms with \(d=4k\). Those discarded terms are
$$\sum_{k=1}^{\lfloor N/4\rfloor} 4k\left\lfloor\frac{N}{4k}\right\rfloor.$$
Since \(\left\lfloor N/(4k)\right\rfloor=\left\lfloor \left\lfloor N/4\right\rfloor /k\right\rfloor\), this becomes
$$4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right).$$
Hence the whole problem collapses to the closed form
$$\boxed{T(r)=1+8\left(S(N)-4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)\right),\qquad N=r^2.}$$
A naive evaluation of \(S(N)\) would still be linear in \(N\). The implementation avoids that by exploiting repeated values of \(\left\lfloor N/d\right\rfloor\).
Let
$$M=\left\lfloor\sqrt N\right\rfloor.$$
For the small divisors \(1\le d\le M\), compute the terms directly:
$$\sum_{d=1}^{M} d\left\lfloor\frac{N}{d}\right\rfloor.$$
For large divisors \(d>M\), group them by the common quotient
$$q=\left\lfloor\frac{N}{d}\right\rfloor.$$
All \(d\) producing the same \(q\) lie in the interval
$$L_q=\left\lfloor\frac{N}{q+1}\right\rfloor+1,\qquad R_q=\left\lfloor\frac{N}{q}\right\rfloor.$$
Only the portion above \(M\) belongs to the second half, so the effective lower bound is \(\max(M+1,L_q)\). The grouped contribution is then
$$q\sum_{d=\max(M+1,L_q)}^{R_q} d,$$
and the inner sum is an arithmetic progression:
$$\sum_{d=l}^{r} d=\frac{(l+r)(r-l+1)}{2}.$$
This split-hyperbola decomposition visits only about \(2\sqrt N\) meaningful ranges.
The target answer is needed modulo
$$P=10^9+7.$$
So every addition and multiplication is reduced modulo \(P\). The division by \(2\) in the arithmetic-series formula is replaced by the modular inverse
$$2^{-1}\equiv 500000004 \pmod{P}.$$
Because the arithmetic-series sum is an exact integer before reduction, performing the reduction at every step preserves the correct final residue.
Here \(N=r^2=4\). First compute
$$S(4)=1\cdot 4+2\cdot 2+3\cdot 1+4\cdot 1=15.$$
Also, \(\left\lfloor N/4\right\rfloor=1\), so
$$S(1)=1.$$
Substituting into the closed form gives
$$T(2)=1+8(15-4\cdot 1)=1+8\cdot 11=89.$$
This matches the standard checkpoint for the problem and confirms that the divisor-sum reformulation is correct.
The C++, Python, and Java implementations all evaluate the same formula
$$T(r)=1+8\left(S(r^2)-4S\!\left(\left\lfloor\frac{r^2}{4}\right\rfloor\right)\right)\pmod{10^9+7}.$$
Each implementation first computes an integer square root to split the summation for \(S(N)\) into a direct part and a grouped part. The direct part handles small divisors one by one. The grouped part iterates over quotient values \(q\), reconstructs the divisor interval that shares that quotient, clips the interval so that it stays strictly above \(\sqrt N\), and then adds the interval using the arithmetic-series formula.
The implementations keep every intermediate result modulo \(10^9+7\). The Python and Java versions partition the two summation phases across available worker tasks, while the C++ version performs the same mathematics in a single-threaded pass with careful wide-integer multiplication for safety. Despite those engineering differences, all three implementations are computing exactly the same divisor decomposition.
For one evaluation of \(S(N)\), the direct loop has length \(\lfloor\sqrt N\rfloor\), and the grouped loop also runs over only \(O(\sqrt N)\) distinct quotient values. Therefore
$$S(N)\text{ can be evaluated in }O(\sqrt N)\text{ time}.$$
The final answer requires two such evaluations, namely at \(N=r^2\) and at \(\left\lfloor N/4\right\rfloor\), so the asymptotic running time remains \(O(\sqrt N)\). The serial method uses \(O(1)\) auxiliary memory, and the parallel variants add only modest task-management overhead on top of the same \(O(\sqrt N)\) total work.
Definiere
$$T(r)=\#\left\{(x_1,x_2,x_3,x_4)\in\mathbb Z^4: x_1^2+x_2^2+x_3^2+x_4^2\le r^2\right\}.$$
Gesucht ist also die Anzahl ganzzahliger Gitterpunkte im vierdimensionalen Ball mit Radius \(r\). Für die eigentliche Aufgabe wird \(r=10^8\) eingesetzt und das Ergebnis modulo \(10^9+7\) verlangt. Eine direkte Durchmusterung aller ganzzahligen Vierer-Tupel ist ausgeschlossen; deshalb wird das geometrische Problem in eine Divisorensumme umgeschrieben.
Der zentrale Trick besteht darin, die Punkte nach ihrem quadrierten Abstand vom Ursprung zu gruppieren.
Setze \(N=r^2\). Für jedes \(n\ge 0\) bezeichne \(r_4(n)\) die Anzahl ganzzahliger Vierer-Tupel mit
$$x_1^2+x_2^2+x_3^2+x_4^2=n.$$
Jeder Gitterpunkt im Ball besitzt genau einen solchen Wert \(n\) mit \(0\le n\le N\). Daher gilt
$$T(r)=\sum_{n=0}^{N} r_4(n).$$
Damit ist die Geometrie auf eine arithmetische Summation zurückgeführt.
Für \(n>0\) liefert Jacobis Vier-Quadrate-Theorem
$$r_4(n)=8\sum_{\substack{d\mid n\\4\nmid d}} d,$$
und zusätzlich gilt \(r_4(0)=1\). Einsetzen ergibt
$$T(r)=1+8\sum_{n=1}^{N}\sum_{\substack{d\mid n\\4\nmid d}} d.$$
Nun werden die Summen vertauscht. Ein fester Divisor \(d\) tritt für alle Vielfachen von \(d\) bis \(N\) auf, also genau \(\left\lfloor N/d\right\rfloor\)-mal. Deshalb
$$T(r)=1+8\sum_{\substack{d\le N\\4\nmid d}} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Definiere die Summenfunktion
$$S(N)=\sum_{d=1}^{N} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Dann erhält man die gesuchten Terme mit \(4\nmid d\), indem man die Beiträge der Form \(d=4k\) entfernt. Diese Beiträge sind
$$\sum_{k=1}^{\lfloor N/4\rfloor} 4k\left\lfloor\frac{N}{4k}\right\rfloor.$$
Wegen \(\left\lfloor N/(4k)\right\rfloor=\left\lfloor \left\lfloor N/4\right\rfloor /k\right\rfloor\) wird daraus
$$4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right).$$
Somit folgt die geschlossene Formel
$$\boxed{T(r)=1+8\left(S(N)-4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)\right),\qquad N=r^2.}$$
Naiv wäre \(S(N)\) noch immer linear in \(N\). Die Lösung nutzt daher aus, dass der Quotient \(\left\lfloor N/d\right\rfloor\) viele Wiederholungen besitzt.
Setze
$$M=\left\lfloor\sqrt N\right\rfloor.$$
Für die kleinen Divisoren \(1\le d\le M\) summiert man direkt:
$$\sum_{d=1}^{M} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Für große Divisoren \(d>M\) gruppiert man nach dem gemeinsamen Quotienten
$$q=\left\lfloor\frac{N}{d}\right\rfloor.$$
Alle \(d\) mit demselben \(q\) liegen im Intervall
$$L_q=\left\lfloor\frac{N}{q+1}\right\rfloor+1,\qquad R_q=\left\lfloor\frac{N}{q}\right\rfloor.$$
Für den zweiten Teil zählt nur der Bereich oberhalb von \(M\), also beginnt man effektiv bei \(\max(M+1,L_q)\). Der gesamte Gruppenbeitrag lautet damit
$$q\sum_{d=\max(M+1,L_q)}^{R_q} d,$$
wobei die innere Summe als arithmetische Reihe geschrieben wird:
$$\sum_{d=l}^{r} d=\frac{(l+r)(r-l+1)}{2}.$$
Genau diese Zerlegung macht die Laufzeit nahezu proportional zu \(\sqrt N\).
Die Zielgröße wird nur modulo
$$P=10^9+7$$
benötigt. Deshalb werden alle Additionen und Multiplikationen fortlaufend modulo \(P\) reduziert. Die Division durch \(2\) in der Formel für die arithmetische Reihe wird durch das multiplikative Inverse
$$2^{-1}\equiv 500000004 \pmod{P}$$
ersetzt. Da die Reihensumme vor der Reduktion ganzzahlig ist, bleibt das Resultat modulo \(P\) exakt.
Hier ist \(N=r^2=4\). Zunächst
$$S(4)=1\cdot 4+2\cdot 2+3\cdot 1+4\cdot 1=15.$$
Außerdem gilt \(\left\lfloor N/4\right\rfloor=1\), also
$$S(1)=1.$$
Damit folgt
$$T(2)=1+8(15-4\cdot 1)=1+8\cdot 11=89.$$
Das stimmt mit dem bekannten Kontrollwert überein und bestätigt die Umformung.
Die C++-, Python- und Java-Implementierungen werten alle dieselbe Formel aus, nämlich
$$T(r)=1+8\left(S(r^2)-4S\!\left(\left\lfloor\frac{r^2}{4}\right\rfloor\right)\right)\pmod{10^9+7}.$$
Zuerst wird eine ganzzahlige Quadratwurzel berechnet, um \(S(N)\) in einen direkten Teil und einen gruppierten Teil aufzuteilen. Der direkte Teil verarbeitet kleine Divisoren einzeln. Der gruppierte Teil läuft über die möglichen Quotienten \(q\), rekonstruiert das dazugehörige Divisorenintervall, schneidet es auf den Bereich oberhalb von \(\sqrt N\) zu und addiert den gesamten Block mit der Formel für die arithmetische Reihe.
Alle Zwischenwerte werden modulo \(10^9+7\) gehalten. Die Python- und Java-Implementierungen teilen die beiden Summationsphasen auf verfügbare Worker auf, während die C++-Implementierung dieselbe Mathematik seriell mit vorsichtiger Ganzzahlarithmetik ausführt. Inhaltlich berechnen alle drei Programme aber exakt dieselbe Zerlegung der Divisorensumme.
Eine Auswertung von \(S(N)\) benötigt \(O(\sqrt N)\) Zeit, weil sowohl der direkte Bereich bis \(\lfloor\sqrt N\rfloor\) als auch die Anzahl der unterschiedlichen Quotienten darüber nur diese Größenordnung haben. Für die Gesamtlösung werden \(S(N)\) und \(S(\lfloor N/4\rfloor)\) berechnet, daher bleibt die asymptotische Laufzeit \(O(\sqrt N)\). Die serielle Variante benötigt \(O(1)\) Zusatzspeicher; die parallelen Varianten haben darüber hinaus nur geringen Verwaltungsaufwand für ihre Aufgabenaufteilung.
Şunu tanımlayalım:
$$T(r)=\#\left\{(x_1,x_2,x_3,x_4)\in\mathbb Z^4: x_1^2+x_2^2+x_3^2+x_4^2\le r^2\right\}.$$
Burada aranan değer, dört boyutta yarıçapı \(r\) olan hiperkürenin içinde kalan tüm tamsayı kafes noktalarının sayısıdır. Asıl görevde \(r=10^8\) için sonuç \(10^9+7\) modunda istenir. Doğrudan nokta taraması mümkün olmadığından çözüm, geometriyi bölen toplamına dönüştürür.
Temel fikir, noktaları orijine olan karesel uzaklıklarına göre kabuk kabuk saymaktır.
\(N=r^2\) olsun. Her \(n\ge 0\) için \(r_4(n)\),
$$x_1^2+x_2^2+x_3^2+x_4^2=n$$
eşitliğini sağlayan tamsayı dörtlülerinin sayısı olsun. O zaman hiperkürenin içindeki her nokta tam olarak bir \(n\) değerine karşılık gelir ve
$$T(r)=\sum_{n=0}^{N} r_4(n)$$
olur. Böylece geometrik sayım aritmetik bir toplam haline gelir.
\(n>0\) için Jacobi teoremi
$$r_4(n)=8\sum_{\substack{d\mid n\\4\nmid d}} d$$
sonucunu verir; ayrıca \(r_4(0)=1\) olur. Bunu yerine yazarsak
$$T(r)=1+8\sum_{n=1}^{N}\sum_{\substack{d\mid n\\4\nmid d}} d$$
elde edilir. Şimdi toplamların yerini değiştiririz. Sabit bir \(d\), \(N\)'ye kadar olan katları için tam olarak \(\left\lfloor N/d\right\rfloor\) kez görünür. Dolayısıyla
$$T(r)=1+8\sum_{\substack{d\le N\\4\nmid d}} d\left\lfloor\frac{N}{d}\right\rfloor$$
olur.
Şimdi
$$S(N)=\sum_{d=1}^{N} d\left\lfloor\frac{N}{d}\right\rfloor$$
fonksiyonunu tanımlayalım. \(4\nmid d\) koşulunu uygulamak için \(d=4k\) olan terimleri çıkarırız. Bunlar
$$\sum_{k=1}^{\lfloor N/4\rfloor} 4k\left\lfloor\frac{N}{4k}\right\rfloor$$
şeklindedir. Ayrıca
$$\left\lfloor\frac{N}{4k}\right\rfloor=\left\lfloor \frac{\left\lfloor N/4\right\rfloor}{k}\right\rfloor$$
olduğundan bu toplam tam olarak
$$4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)$$
eder. Böylece kapalı formül
$$\boxed{T(r)=1+8\left(S(N)-4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)\right),\qquad N=r^2}$$
olarak bulunur.
\(S(N)\)'yi doğrudan toplamak hâlâ çok pahalıdır. Bunun yerine \(\left\lfloor N/d\right\rfloor\) bölümünün uzun aralıklar boyunca sabit kalmasından yararlanılır.
Şunu alalım:
$$M=\left\lfloor\sqrt N\right\rfloor.$$
Küçük bölenler için doğrudan toplarız:
$$\sum_{d=1}^{M} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Büyük bölenlerde ise
$$q=\left\lfloor\frac{N}{d}\right\rfloor$$
sabit kalan aralıklar kullanılır. Aynı \(q\) değerini veren tüm \(d\)'ler
$$L_q=\left\lfloor\frac{N}{q+1}\right\rfloor+1,\qquad R_q=\left\lfloor\frac{N}{q}\right\rfloor$$
aralığındadır. İkinci kısım yalnızca \(M\)'den büyük bölenleri içerdiği için alt sınır fiilen \(\max(M+1,L_q)\) olur. Grup katkısı da
$$q\sum_{d=\max(M+1,L_q)}^{R_q} d$$
şeklinde yazılır. İç toplam bir aritmetik dizi toplamıdır:
$$\sum_{d=l}^{r} d=\frac{(l+r)(r-l+1)}{2}.$$
Bu düzenleme yaklaşık \(2\sqrt N\) anlamlı aralıkla işi bitirir.
Sonuç sadece
$$P=10^9+7$$
modunda gerektiği için, tüm toplama ve çarpma işlemleri sürekli mod \(P\) altında tutulur. Aritmetik dizi formülündeki \(2\)'ye bölme işlemi, modüler ters kullanılarak
$$2^{-1}\equiv 500000004 \pmod{P}$$
ile yapılır. Toplamın tam sayı olması sayesinde ara adımlarda mod almak nihai kalanı bozmaz.
Bu durumda \(N=r^2=4\). Önce
$$S(4)=1\cdot 4+2\cdot 2+3\cdot 1+4\cdot 1=15$$
bulunur. Ayrıca \(\left\lfloor N/4\right\rfloor=1\) olduğundan
$$S(1)=1.$$
Kapalı formüle yerleştirince
$$T(2)=1+8(15-4\cdot 1)=1+8\cdot 11=89$$
elde edilir. Bu, problemin bilinen küçük doğrulama değeridir.
C++, Python ve Java implementasyonları aynı matematiksel ifadeyi hesaplar:
$$T(r)=1+8\left(S(r^2)-4S\!\left(\left\lfloor\frac{r^2}{4}\right\rfloor\right)\right)\pmod{10^9+7}.$$
Önce tam sayı karekök bulunur ve \(S(N)\) hesabı iki parçaya ayrılır. İlk parça küçük bölenleri tek tek toplar. İkinci parça, bölüm değeri aynı kalan \(q\) gruplarını dolaşır; bu grupların bölen aralığı yeniden kurulur, aralık \(\sqrt N\)'nin üstünde kalacak şekilde kırpılır ve aritmetik dizi formülüyle tek adımda eklenir.
Tüm ara sonuçlar mod \(10^9+7\) altında tutulur. Python ve Java implementasyonları bu iki toplama aşamasını uygun işçilere bölerek paralelleştirir; C++ implementasyonu ise aynı hesabı tek iş parçacığında güvenli geniş tamsayı çarpımlarıyla yürütür. Matematiksel olarak üçü de aynı bölen ayrışımını uygular.
Bir \(S(N)\) hesabında hem doğrudan bölüm hem de gruplanmış bölüm yalnızca \(O(\sqrt N)\) büyüklüğündedir; dolayısıyla süre karmaşıklığı \(O(\sqrt N)\) olur. Son cevapta \(S(N)\) ve \(S(\lfloor N/4\rfloor)\) hesaplandığı için toplam asimptotik süre değişmez. Seri yaklaşım \(O(1)\) ek bellek kullanır; paralel sürümlerde buna ek olarak yalnızca küçük görev yönetim maliyetleri vardır.
Definimos
$$T(r)=\#\left\{(x_1,x_2,x_3,x_4)\in\mathbb Z^4: x_1^2+x_2^2+x_3^2+x_4^2\le r^2\right\}.$$
Hay que contar, por tanto, cuántos puntos de la red entera en cuatro dimensiones caen dentro de la hiperesfera de radio \(r\). En el desafío real se toma \(r=10^8\) y se pide la respuesta módulo \(10^9+7\). Enumerar directamente todos los cuádruples enteros es inviable, así que la solución transforma el problema geométrico en una suma sobre divisores.
La idea central es contar la hiperesfera capa por capa según la distancia cuadrada al origen.
Sea \(N=r^2\). Para cada entero \(n\ge 0\), denotemos por \(r_4(n)\) el número de cuádruples enteros tales que
$$x_1^2+x_2^2+x_3^2+x_4^2=n.$$
Cada punto de la red dentro de la bola corresponde exactamente a un valor \(n\) con \(0\le n\le N\). Por ello,
$$T(r)=\sum_{n=0}^{N} r_4(n).$$
Así, el conteo geométrico se convierte en un problema aritmético.
Para \(n>0\), el teorema de Jacobi afirma que
$$r_4(n)=8\sum_{\substack{d\mid n\\4\nmid d}} d,$$
mientras que \(r_4(0)=1\). Sustituyendo en la expresión anterior se obtiene
$$T(r)=1+8\sum_{n=1}^{N}\sum_{\substack{d\mid n\\4\nmid d}} d.$$
Ahora intercambiamos el orden de las sumas. Un divisor fijo \(d\) contribuye para cada múltiplo suyo hasta \(N\), es decir, exactamente \(\left\lfloor N/d\right\rfloor\) veces. Entonces
$$T(r)=1+8\sum_{\substack{d\le N\\4\nmid d}} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Introduzcamos la función
$$S(N)=\sum_{d=1}^{N} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Los términos prohibidos son exactamente aquellos con \(d=4k\). Su contribución es
$$\sum_{k=1}^{\lfloor N/4\rfloor} 4k\left\lfloor\frac{N}{4k}\right\rfloor.$$
Como \(\left\lfloor N/(4k)\right\rfloor=\left\lfloor \left\lfloor N/4\right\rfloor /k\right\rfloor\), esa suma se reescribe como
$$4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right).$$
Por tanto, llegamos a la fórmula cerrada
$$\boxed{T(r)=1+8\left(S(N)-4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)\right),\qquad N=r^2.}$$
Calcular \(S(N)\) término a término seguiría siendo demasiado costoso. La mejora consiste en observar que el cociente \(\left\lfloor N/d\right\rfloor\) repite muchos valores.
Tomemos
$$M=\left\lfloor\sqrt N\right\rfloor.$$
Para los divisores pequeños \(1\le d\le M\), la suma se evalúa directamente:
$$\sum_{d=1}^{M} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Para los divisores grandes \(d>M\), agrupamos por el cociente común
$$q=\left\lfloor\frac{N}{d}\right\rfloor.$$
Todos los \(d\) que producen el mismo \(q\) forman el intervalo
$$L_q=\left\lfloor\frac{N}{q+1}\right\rfloor+1,\qquad R_q=\left\lfloor\frac{N}{q}\right\rfloor.$$
En la segunda mitad solo cuentan los divisores por encima de \(M\), así que el límite inferior real es \(\max(M+1,L_q)\). La contribución agrupada pasa a ser
$$q\sum_{d=\max(M+1,L_q)}^{R_q} d,$$
y la suma interior se cierra con la fórmula de progresión aritmética
$$\sum_{d=l}^{r} d=\frac{(l+r)(r-l+1)}{2}.$$
La respuesta solo se necesita módulo
$$P=10^9+7.$$
Por eso cada suma y cada producto se reducen módulo \(P\). La división entre \(2\) que aparece en la progresión aritmética se reemplaza por el inverso modular
$$2^{-1}\equiv 500000004 \pmod{P}.$$
Como la suma de una progresión aritmética es un entero exacto antes de modular, esta reducción paso a paso conserva el residuo correcto.
Aquí \(N=r^2=4\). Primero
$$S(4)=1\cdot 4+2\cdot 2+3\cdot 1+4\cdot 1=15.$$
Además, \(\left\lfloor N/4\right\rfloor=1\), así que
$$S(1)=1.$$
Entonces
$$T(2)=1+8(15-4\cdot 1)=1+8\cdot 11=89.$$
Este valor coincide con el punto de control pequeño del problema y muestra que la reformulación es correcta.
Las implementaciones en C++, Python y Java evalúan exactamente la misma identidad:
$$T(r)=1+8\left(S(r^2)-4S\!\left(\left\lfloor\frac{r^2}{4}\right\rfloor\right)\right)\pmod{10^9+7}.$$
Cada implementación calcula primero una raíz cuadrada entera para dividir el trabajo de \(S(N)\) en una parte directa y otra agrupada. La parte directa recorre uno a uno los divisores pequeños. La parte agrupada itera sobre los posibles valores de \(q\), reconstruye el intervalo de divisores que comparten ese cociente, recorta el intervalo para quedarse solo con los divisores mayores que \(\sqrt N\), y suma todo el bloque con la fórmula de progresión aritmética.
Todos los valores intermedios se mantienen módulo \(10^9+7\). Las versiones de Python y Java reparten las dos fases de suma entre varios trabajadores disponibles, mientras que la versión de C++ hace el mismo cálculo en una sola pasada con aritmética entera ancha para evitar problemas de rango. Desde el punto de vista matemático, las tres versiones implementan la misma descomposición por divisores.
Una evaluación de \(S(N)\) requiere \(O(\sqrt N)\) operaciones, porque la parte directa llega hasta \(\lfloor\sqrt N\rfloor\) y la parte agrupada solo recorre \(O(\sqrt N)\) cocientes distintos. La solución final necesita dos evaluaciones, \(S(N)\) y \(S(\lfloor N/4\rfloor)\), por lo que la complejidad asintótica total sigue siendo \(O(\sqrt N)\). La versión secuencial usa \(O(1)\) memoria auxiliar, y las versiones paralelas solo añaden una pequeña sobrecarga de planificación.
定义
$$T(r)=\#\left\{(x_1,x_2,x_3,x_4)\in\mathbb Z^4: x_1^2+x_2^2+x_3^2+x_4^2\le r^2\right\}.$$
也就是说,我们要统计四维空间中所有位于半径为 \(r\) 的超球内部的整数格点个数。原题要求在 \(r=10^8\) 时求出这个数量,并对 \(10^9+7\) 取模。若直接枚举所有整数四元组,规模完全不可接受,因此解法必须把几何计数改写成更适合数论处理的形式。
核心思想是按照点到原点的平方距离,把整个四维超球拆成一层一层的“球壳”来计数。
令 \(N=r^2\)。对每个整数 \(n\ge 0\),记 \(r_4(n)\) 为满足
$$x_1^2+x_2^2+x_3^2+x_4^2=n$$
的整数四元组个数。超球内部的每个格点都恰好对应某个 \(0\le n\le N\) 的平方距离,因此
$$T(r)=\sum_{n=0}^{N} r_4(n).$$
这样一来,原来的几何问题就被转化成了一个关于四平方表示数的求和问题。
对 \(n>0\),Jacobi 四平方定理给出
$$r_4(n)=8\sum_{\substack{d\mid n\\4\nmid d}} d,$$
而 \(r_4(0)=1\)。代回上一式可得
$$T(r)=1+8\sum_{n=1}^{N}\sum_{\substack{d\mid n\\4\nmid d}} d.$$
接下来交换求和顺序。固定一个除数 \(d\),它会对所有不超过 \(N\) 的 \(d\) 的倍数贡献一次,因此总共出现
$$\left\lfloor\frac{N}{d}\right\rfloor$$
次。于是
$$T(r)=1+8\sum_{\substack{d\le N\\4\nmid d}} d\left\lfloor\frac{N}{d}\right\rfloor.$$
到这里,问题已经从“点是否在球内”变成了“带权除数求和”。
定义一个辅助求和函数
$$S(N)=\sum_{d=1}^{N} d\left\lfloor\frac{N}{d}\right\rfloor.$$
那么只保留 \(4\nmid d\) 的项,就等于从全部项中减去 \(d=4k\) 的部分。被减掉的部分是
$$\sum_{k=1}^{\lfloor N/4\rfloor} 4k\left\lfloor\frac{N}{4k}\right\rfloor.$$
由于
$$\left\lfloor\frac{N}{4k}\right\rfloor=\left\lfloor \frac{\left\lfloor N/4\right\rfloor}{k}\right\rfloor,$$
所以上式恰好等于
$$4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right).$$
于是整个题目的主公式就化为
$$\boxed{T(r)=1+8\left(S(N)-4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)\right),\qquad N=r^2.}$$
这一步非常关键,因为它把四平方表示数的求和彻底压缩成了两个同类型的求和函数。
如果逐项计算 \(S(N)\),仍然需要 \(O(N)\) 时间。真正的加速来自于观察到
$$\left\lfloor\frac{N}{d}\right\rfloor$$
在很长的一段区间内会保持不变。
记
$$M=\left\lfloor\sqrt N\right\rfloor.$$
当 \(1\le d\le M\) 时,直接累加
$$\sum_{d=1}^{M} d\left\lfloor\frac{N}{d}\right\rfloor.$$
当 \(d>M\) 时,不再按除数逐个处理,而是按商值
$$q=\left\lfloor\frac{N}{d}\right\rfloor$$
分组。所有产生同一个 \(q\) 的除数 \(d\) 都落在区间
$$L_q=\left\lfloor\frac{N}{q+1}\right\rfloor+1,\qquad R_q=\left\lfloor\frac{N}{q}\right\rfloor.$$
由于第二部分只负责 \(d>M\) 的那些项,所以实际下界要改成 \(\max(M+1,L_q)\)。对应的一整组贡献为
$$q\sum_{d=\max(M+1,L_q)}^{R_q} d.$$
而区间和可以用等差数列公式一次完成:
$$\sum_{d=l}^{r} d=\frac{(l+r)(r-l+1)}{2}.$$
这样就不再需要遍历所有 \(d\),而只需要遍历大约 \(2\sqrt N\) 个有意义的区间,因此总时间复杂度下降到 \(O(\sqrt N)\)。
题目最终只要求模
$$P=10^9+7$$
的结果,所以实现中会在每一步都对 \(P\) 取模。等差数列求和公式中的除以 \(2\),通过模逆元来完成:
$$2^{-1}\equiv 500000004 \pmod{P}.$$
因为区间和在取模之前本来就是精确整数,所以把加法、乘法和除法都搬到模运算下处理,不会改变最终答案的同余类。
这是一个非常适合手算的检查点。此时 \(N=r^2=4\)。先算
$$S(4)=1\cdot 4+2\cdot 2+3\cdot 1+4\cdot 1=15.$$
再算
$$\left\lfloor\frac{N}{4}\right\rfloor=1,\qquad S(1)=1.$$
代入主公式:
$$T(2)=1+8(15-4\cdot 1)=1+8\cdot 11=89.$$
这正是该题的小规模校验值,因此说明推导和实现方向都是正确的。
C++、Python 和 Java 三个实现都围绕同一个公式展开:
$$T(r)=1+8\left(S(r^2)-4S\!\left(\left\lfloor\frac{r^2}{4}\right\rfloor\right)\right)\pmod{10^9+7}.$$
实现时,首先计算整数平方根,把 \(S(N)\) 的求和分成两段。前一段逐个处理较小的除数。后一段不再直接枚举除数,而是枚举可能的商值 \(q\),据此反推出所有对应除数构成的连续区间,然后用等差数列求和公式把整段一次加入。区间的下界会被裁到 \(\sqrt N\) 以上,以避免与前一段重复。
所有中间结果都持续按 \(10^9+7\) 取模。Python 和 Java 实现把“直接求和”和“按商分组求和”这两部分再分配给多个工作任务,以利用多核;C++ 实现则保持单线程,但用足够宽的整数乘法来确保模乘安全。尽管工程细节略有不同,三种实现计算的都是同一套除数分组公式。
单次计算 \(S(N)\) 时,直接部分需要处理 \(\lfloor\sqrt N\rfloor\) 项,而分组部分也只会遍历 \(O(\sqrt N)\) 个不同的商值,因此总时间复杂度为 \(O(\sqrt N)\)。最终答案需要分别计算 \(S(N)\) 与 \(S(\lfloor N/4\rfloor)\),但这不会改变渐近阶。串行版本的额外空间复杂度为 \(O(1)\),并行版本只是在此基础上增加少量任务管理开销。
Определим
$$T(r)=\#\left\{(x_1,x_2,x_3,x_4)\in\mathbb Z^4: x_1^2+x_2^2+x_3^2+x_4^2\le r^2\right\}.$$
Нужно посчитать число целочисленных точек в четырёхмерном шаре радиуса \(r\). В самой задаче берётся \(r=10^8\), а ответ требуется по модулю \(10^9+7\). Полный перебор целочисленных четвёрок невозможен, поэтому решение переводит геометрический вопрос в арифметическую сумму по делителям.
Главная идея состоит в том, чтобы считать точки не напрямую, а по слоям с фиксированным квадратом расстояния до начала координат.
Положим \(N=r^2\). Для каждого \(n\ge 0\) обозначим через \(r_4(n)\) количество целочисленных четвёрок, удовлетворяющих
$$x_1^2+x_2^2+x_3^2+x_4^2=n.$$
Каждая точка внутри шара имеет единственное такое значение \(n\), причём \(0\le n\le N\). Следовательно,
$$T(r)=\sum_{n=0}^{N} r_4(n).$$
Тем самым геометрическое условие заменяется задачей о сумме функции представлений в виде четырёх квадратов.
Для \(n>0\) теорема Якоби даёт формулу
$$r_4(n)=8\sum_{\substack{d\mid n\\4\nmid d}} d,$$
а также \(r_4(0)=1\). Подставляя это в предыдущую сумму, получаем
$$T(r)=1+8\sum_{n=1}^{N}\sum_{\substack{d\mid n\\4\nmid d}} d.$$
Теперь меняем порядок суммирования. Фиксированный делитель \(d\) встречается у всех кратных \(d\), не превосходящих \(N\), то есть ровно
$$\left\lfloor\frac{N}{d}\right\rfloor$$
раз. Поэтому
$$T(r)=1+8\sum_{\substack{d\le N\\4\nmid d}} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Введём функцию
$$S(N)=\sum_{d=1}^{N} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Тогда нужная сумма по \(d\), не делящимся на \(4\), получается вычитанием вкладов \(d=4k\). Эти вклады равны
$$\sum_{k=1}^{\lfloor N/4\rfloor} 4k\left\lfloor\frac{N}{4k}\right\rfloor.$$
Поскольку
$$\left\lfloor\frac{N}{4k}\right\rfloor=\left\lfloor \frac{\left\lfloor N/4\right\rfloor}{k}\right\rfloor,$$
эта сумма точно совпадает с
$$4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right).$$
Итак, получаем основную формулу задачи:
$$\boxed{T(r)=1+8\left(S(N)-4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)\right),\qquad N=r^2.}$$
Если суммировать \(S(N)\) напрямую, получится линейный алгоритм. Ускорение возникает из-за того, что значение
$$\left\lfloor\frac{N}{d}\right\rfloor$$
много раз повторяется.
Положим
$$M=\left\lfloor\sqrt N\right\rfloor.$$
Для малых делителей \(1\le d\le M\) слагаемые считаются напрямую:
$$\sum_{d=1}^{M} d\left\lfloor\frac{N}{d}\right\rfloor.$$
Для больших делителей \(d>M\) элементы группируются по общему частному
$$q=\left\lfloor\frac{N}{d}\right\rfloor.$$
Все \(d\), соответствующие одному и тому же \(q\), образуют отрезок
$$L_q=\left\lfloor\frac{N}{q+1}\right\rfloor+1,\qquad R_q=\left\lfloor\frac{N}{q}\right\rfloor.$$
Во второй части нужны только \(d>M\), поэтому реальная нижняя граница равна \(\max(M+1,L_q)\). Вклад целого блока записывается так:
$$q\sum_{d=\max(M+1,L_q)}^{R_q} d.$$
Внутренняя сумма вычисляется формулой арифметической прогрессии:
$$\sum_{d=l}^{r} d=\frac{(l+r)(r-l+1)}{2}.$$
Благодаря этому приходится обрабатывать только порядка \(2\sqrt N\) существенных диапазонов.
Ответ нужен по модулю
$$P=10^9+7.$$
Поэтому все промежуточные сложения и умножения немедленно приводятся по модулю \(P\). Деление на \(2\) в формуле суммы арифметической прогрессии заменяется на умножение на обратный элемент
$$2^{-1}\equiv 500000004 \pmod{P}.$$
Так как сама сумма прогрессии до взятия модуля является точным целым числом, такая замена полностью корректна.
Здесь \(N=r^2=4\). Сначала вычислим
$$S(4)=1\cdot 4+2\cdot 2+3\cdot 1+4\cdot 1=15.$$
Далее \(\left\lfloor N/4\right\rfloor=1\), значит
$$S(1)=1.$$
Подставляем в основную формулу:
$$T(2)=1+8(15-4\cdot 1)=1+8\cdot 11=89.$$
Это совпадает с известной контрольной точкой и служит хорошей проверкой вывода.
Реализации на C++, Python и Java вычисляют одну и ту же формулу:
$$T(r)=1+8\left(S(r^2)-4S\!\left(\left\lfloor\frac{r^2}{4}\right\rfloor\right)\right)\pmod{10^9+7}.$$
Сначала находится целая квадратная корень, чтобы разбить вычисление \(S(N)\) на две части. Первая часть перебирает малые делители по одному. Вторая часть проходит по возможным значениям частного \(q\), восстанавливает интервал делителей с таким частным, обрезает его так, чтобы он лежал строго выше \(\sqrt N\), и добавляет вклад всего интервала через формулу арифметической прогрессии.
Все промежуточные значения сохраняются по модулю \(10^9+7\). Реализации на Python и Java дополнительно делят обе фазы суммирования между доступными рабочими задачами, а реализация на C++ выполняет те же вычисления последовательно, используя достаточно широкую целочисленную арифметику для безопасного умножения. Несмотря на эти инженерные различия, математический алгоритм у всех трёх версий одинаков.
Одно вычисление \(S(N)\) занимает \(O(\sqrt N)\) времени: прямая часть проходит до \(\lfloor\sqrt N\rfloor\), а сгруппированная часть обрабатывает только \(O(\sqrt N)\) различных частных. Итоговая формула требует два таких вычисления, для \(N\) и \(\lfloor N/4\rfloor\), поэтому асимптотика остаётся \(O(\sqrt N)\). В последовательной версии используется \(O(1)\) дополнительной памяти; в параллельных версиях сверху добавляется лишь небольшой служебный расход на управление задачами.
نعرّف
$$T(r)=\#\left\{(x_1,x_2,x_3,x_4)\in\mathbb Z^4: x_1^2+x_2^2+x_3^2+x_4^2\le r^2\right\}.$$
المطلوب هو عدد نقاط الشبكة الصحيحة داخل الكرة الفائقة رباعية الأبعاد ذات نصف القطر \(r\). في النسخة الفعلية من المسألة نأخذ \(r=10^8\)، ثم نعيد الجواب بترديد \(10^9+7\). العدّ المباشر لكل الرباعيات الصحيحة مستحيل عملياً، لذلك يحوّل الحل المسألة الهندسية إلى مجموع عددي يعتمد على القواسم.
الفكرة الأساسية هي عدّ النقاط طبقةً طبقة بحسب مربع بعدها عن الأصل.
لنضع \(N=r^2\). ولكل عدد صحيح \(n\ge 0\)، نرمز بـ \(r_4(n)\) إلى عدد الرباعيات الصحيحة التي تحقق
$$x_1^2+x_2^2+x_3^2+x_4^2=n.$$
كل نقطة صحيحة داخل الكرة الفائقة تمتلك قيمة وحيدة من هذا النوع بين \(0\) و\(N\)، ولذلك
$$T(r)=\sum_{n=0}^{N} r_4(n).$$
بهذا تختفي الهندسة من الواجهة، ويصبح المطلوب مجموعاً على أعداد التمثيلات بأربعة مربعات.
عندما يكون \(n>0\)، تعطي مبرهنة ياكوبي
$$r_4(n)=8\sum_{\substack{d\mid n\\4\nmid d}} d,$$
ومعها \(r_4(0)=1\). بالتعويض نحصل على
$$T(r)=1+8\sum_{n=1}^{N}\sum_{\substack{d\mid n\\4\nmid d}} d.$$
الآن نبدّل ترتيب الجمع. إذا ثبّتْنا القاسم \(d\)، فإنه يظهر مرة واحدة لكل مضاعف له لا يتجاوز \(N\)، أي
$$\left\lfloor\frac{N}{d}\right\rfloor$$
مرات. ومن ثم
$$T(r)=1+8\sum_{\substack{d\le N\\4\nmid d}} d\left\lfloor\frac{N}{d}\right\rfloor.$$
لنعرّف الدالة
$$S(N)=\sum_{d=1}^{N} d\left\lfloor\frac{N}{d}\right\rfloor.$$
الحدود غير المسموح بها هي بالضبط الحدود التي فيها \(d=4k\). مساهمتها تساوي
$$\sum_{k=1}^{\lfloor N/4\rfloor} 4k\left\lfloor\frac{N}{4k}\right\rfloor.$$
وبما أن
$$\left\lfloor\frac{N}{4k}\right\rfloor=\left\lfloor \frac{\left\lfloor N/4\right\rfloor}{k}\right\rfloor,$$
فإن هذا المجموع يساوي تماماً
$$4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right).$$
إذن تصبح الصيغة النهائية للمسألة
$$\boxed{T(r)=1+8\left(S(N)-4S\!\left(\left\lfloor\frac{N}{4}\right\rfloor\right)\right),\qquad N=r^2.}$$
الحساب المباشر لـ \(S(N)\) يبقى خطياً في \(N\)، وهذا ما نتجنبه. الفكرة هي أن القيمة
$$\left\lfloor\frac{N}{d}\right\rfloor$$
تتكرر على فترات طويلة.
لنضع
$$M=\left\lfloor\sqrt N\right\rfloor.$$
بالنسبة إلى القواسم الصغيرة \(1\le d\le M\)، نجمع مباشرة:
$$\sum_{d=1}^{M} d\left\lfloor\frac{N}{d}\right\rfloor.$$
أما القواسم الكبيرة \(d>M\)، فنجمّعها بحسب خارج القسمة المشترك
$$q=\left\lfloor\frac{N}{d}\right\rfloor.$$
كل القيم \(d\) التي تعطي نفس \(q\) تقع في المجال
$$L_q=\left\lfloor\frac{N}{q+1}\right\rfloor+1,\qquad R_q=\left\lfloor\frac{N}{q}\right\rfloor.$$
ولأن الجزء الثاني يجب أن يشمل فقط القواسم الأكبر من \(M\)، فإن الحد الأدنى الفعلي يصبح \(\max(M+1,L_q)\). عندها تكون مساهمة المجموعة كلها
$$q\sum_{d=\max(M+1,L_q)}^{R_q} d,$$
ويحسب المجموع الداخلي بواسطة صيغة المتتالية الحسابية
$$\sum_{d=l}^{r} d=\frac{(l+r)(r-l+1)}{2}.$$
بهذه الطريقة نمرّ على عدد يقارب \(2\sqrt N\) من المجالات المفيدة فقط، بدلاً من المرور على جميع القواسم حتى \(N\).
الجواب النهائي مطلوب بترديد
$$P=10^9+7.$$
لذلك تُختزل كل عملية جمع وضرب مباشرةً بترديد \(P\). والقسمة على \(2\) في مجموع المتتالية الحسابية تُستبدل بالمعكوس الضربي
$$2^{-1}\equiv 500000004 \pmod{P}.$$
ولأن مجموع المتتالية الحسابية عدد صحيح تماماً قبل أخذ الترديد، فإن إجراء الاختزال في كل خطوة يبقي الباقي النهائي صحيحاً.
في هذه الحالة \(N=r^2=4\). نحسب أولاً
$$S(4)=1\cdot 4+2\cdot 2+3\cdot 1+4\cdot 1=15.$$
وكذلك
$$\left\lfloor\frac{N}{4}\right\rfloor=1,\qquad S(1)=1.$$
إذن
$$T(2)=1+8(15-4\cdot 1)=1+8\cdot 11=89.$$
وهذا يطابق قيمة التحقق الصغيرة المعروفة للمسألة.
تعتمد تطبيقات C++ وPython وJava كلها على الصيغة نفسها:
$$T(r)=1+8\left(S(r^2)-4S\!\left(\left\lfloor\frac{r^2}{4}\right\rfloor\right)\right)\pmod{10^9+7}.$$
تبدأ كل نسخة بحساب الجذر التربيعي الصحيح لتقسيم جمع \(S(N)\) إلى قسمين. القسم الأول يجمع القواسم الصغيرة واحداً واحداً. أما القسم الثاني فيمرّ على قيم خارج القسمة \(q\)، ويعيد بناء مجال القواسم الذي يحقق هذا الخارج، ثم يقتطع منه ما يقع فوق \(\sqrt N\) فقط، وبعد ذلك يضيف مساهمة المجال دفعة واحدة بصيغة المتتالية الحسابية.
كل القيم الوسطية تبقى مختزلة بترديد \(10^9+7\). نسختا Python وJava توزعان مرحلتي الجمع على عدة عمال للاستفادة من التوازي، بينما تنفذ نسخة C++ الحساب نفسه في مسار واحد مع استخدام ضرب صحيح عريض لتأمين سلامة الضرب المعياري. ومع ذلك، فالمضمون الرياضي في اللغات الثلاث واحد تماماً.
حساب واحد للدالة \(S(N)\) يحتاج إلى \(O(\sqrt N)\) من الزمن، لأن الجزء المباشر يصل فقط إلى \(\lfloor\sqrt N\rfloor\)، والجزء المجمّع يمرّ على \(O(\sqrt N)\) من قيم خارج القسمة المختلفة. وبما أن الحل النهائي يحتاج إلى حساب \(S(N)\) و\(S(\lfloor N/4\rfloor)\)، فإن التعقيد الكلي يبقى \(O(\sqrt N)\). النسخة التسلسلية تستخدم \(O(1)\) من الذاكرة الإضافية، أما النسخ المتوازية فتضيف فقط كلفة إدارية بسيطة لإدارة المهام.