Из
Википедии:
Цитата:
A positive integer can be represented as a sum of two squares precisely if its prime factorization contains no odd powers of primes of the form 4k+3.
Дает некоторый простор для размышлений об алгоритме -- например, использующий решето Эратосфена...
Впрочем, я сомневаюсь, что это самый быстрый способ ответа на вопрос. Если
, то можно без ограничения общности считать, что
. Таким образом организовав двойной цикл по
и
, мы все равно имеем линейное время. На Python:
Код:
import math, time
def squares(s):
bitmap = [0 for ix in xrange(0, s+1)] ## инициализируем массив нулями
## для описанного диаапазона a
## / -- выдает результат с плавающей точкой
for a in xrange(int(math.sqrt(s/2)) + 1):
b = a
n = a**2 + b**2
## внутренний цикл по b -- ограничен проверкой n
## одна из причин -- мы не очень точно считаем верхнюю границу a
while n <= s:
bitmap[n] = 1
b += 1
n = a**2 + b**2
return sum(bitmap)-1 ## because 0 is always marked and is not a valid square
def test(s):
start = time.clock()
ns = squares(s)
end = time.clock()
print "%d: %d squares (%.3f secs)" % (s, ns, end - start)
test(4)
test(25)
test(1000000)
test(10000000)
test(100000000)
результат:
Код:
4: 3 squares (0.000 secs)
25: 13 squares (0.000 secs)
1000000: 216341 squares (0.757 secs)
10000000: 1985459 squares (7.318 secs)
100000000: 18457847 squares (90.713 secs)
Некоторая нелинейность (для
) связана с управлением скоростью процессора (защита от перегрева).
Конечно, это все еще можно пытаться оптимизировать. Например, подсчитывая заранее квадраты. Но, вроде, и так не плохо...