Wiąże sie on niestety z faktoryzacją liczby, więć będzie miał taką samą
złożoność jak algoryt naiwny (przeszukanie wszytkich a<=sqrt(n) ).
O(sqrt(n))
W skrocie, faktoryzujesz liczbę n.
Patrzymy na czynniki.
2 = (1^2+1^2)
Czynniki pierwsze postaci p=4k+3 nie mają rozkładu na sumę kwadratów!
To samo, jeśli p występuje w nieparzystej potędze.
https://en.wikipedia.org/wiki/Sum_of_two_squares_theorem
https://en.wikipedia.org/wiki/Fermat%27s_theorem_on_sums_of_two_squares
Parzyste, p^2k, można rozłożyć na trywialną "sumę" 0^2 + (p^k)^2, też się przyda.
Czynniki pierwsze postaci mają jeden rozkład
https://en.wikipedia.org/wiki/Sum_of_squares_function#k_=_2
Włąściwie, w pierwsym z tych przypadków należałoby mówić o 4 przypadkach
(bo mozemy zamienic kolejność i znaki niezerwoego elementu) a wdrugiej
o 8 (kolejnosć x znaki kazdej z liczb).
p^k ma już tak liczonych 4*(k+1) dzielników (dla p == 1 mod 4)
Teraz gwóźdz programu, wzorek skroconego mnozenioa
https://en.wikipedia.org/wiki/Brahmagupta%E2%80%93Fibonacci_identity
w ten sposob, skoro znamy rozkład na sumę kwadratów czynników liczby n,
mozemy wygenerować rozkłady całej liczby.
Jeśli śledzimy wszystkie pary, włącznie z kombinacjami znaków, potrzebujemy
tylko jednej wersji wzorku.
Podsumowując, znajdujesz czynniki pierwsze i odpowiadajace mu wykłądniki,
każdemu generujesz zestaw rozkłądów na sumę kwadratów, a następnie
bierzesz wszystkie kombinacje.
Potem porządkujesz, aby odrzucić kombinacje z ujemnymi i powtorzenia przez zamianę koljeności.
Pewnie da się pozbyć roznych znaków w trzymanych parach przez zastosowanie
obu wzorków, ale musisz sprawdzic, czy nic sie wtedy nie pominie.
Wersja ze znakami się zgadza bo odtwarza wzor na liczbę rozkładów.
Pozostało jeszcze wygenerować rozkłąd dla p = 1 mod 3.
ale ten też jest opisany tu
https://en.wikipedia.org/wiki/Fermat%27s_theorem_on_sums_of_two_squares
Jeśli szukasz rozkłądu konkretnej lczby, pewnie nie ma sensu uzywać tej metodt, ale
jeśli potrzebujesz rozkładu wszytkich liczb od 1 do n i masz pamiec na zobienie tabelki
dzielników, to będzie to znacznie szybciej (choc nadal pesymeistycznie, dla liczb
pierwszych, alg działa w czasie sqrt(n)).
Hmm, w sumie jak lecisz od 1 do n, to od razu można generować rozkłady na bazie
poprzednich wpisów. Takie trochę sito erastotenesa wychodzi.
A nie ma znanego znacznie lepszego algorytmu, inaczej faktoryzacja przynajmniej cześći
liczb byłaby łatwiejsza.
https://en.wikipedia.org/wiki/Euler%27s_factorization_method
bartekltg