From the math principle:
A number N is expressible as a sum of 2 squares if and only if in the prime factorization of N, every prime of the form
(4k+3)
occurs an even number of times!
What I did is pre-calculated all the 4k+3
numbers and checking it's frequency by continuous division.
This program is written in correspondence to the constraints:
1 < T <100
0 < N < 10 ^ 12
import java.util.Scanner;
public class TwoSquaresOrNot {
static int max = 250000;
static long[] nums = new long[max];
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int i = 0; i < max; ++i)
nums[i] = 4 * i + 3;
while (T-- > 0) {
long n = sc.nextLong();
System.out.println((canWrite(n) ? "Yes" : "No"));
}
}
private static boolean canWrite(long n) {
// TODO Auto-generated method stub
for (int i = 0; i < nums.length; ++i) {//loop through all the numbers
if (nums[i] > n)
return true;
int count = 0;
while (n % nums[i] == 0) {
count++;
n /= nums[i];
}
if (count % 2 != 0)//check for odd frequency
return false;
}
return true;
}
}
But this doesn't seem to work in the SPOJ website.
Am I missing something? Or am I doing something wrong?
0
is also considered in this.
Some valid cases are:
1 = 1^2 + 0^2
8 = 2^2 + 2^2
A number can be represented as a sum of two squares precisely when N is of the form n2∏pi where each pi is a prime congruent to 1 mod 4. If the equation a2+1≡a(modp) is solvable for some a, then p can be represented as a sum of two squares.
All positive integers can be expressed as sums of squares. Some can be expressed as the sum of two or three squares, some can be expressed as the sum of a million squares. And some can be expressed expressed as sums of squares in multiple ways. For example, 338350 is the sum of the first hundred nonzero squares.
EDITED AS PER COMMENTS OF OP.
Couple things. First: if you are looking for the prime factorization, you can stop when you are at > sqrt(n), you don't have to go all the way to n.
So your code should become something like:
private static boolean canWrite(long n) {
// TODO Auto-generated method stub
for (int i = 0; i < nums.length; ++i) {//loop through all the numbers
//FIRST CHANGE: Sqrt
if (nums[i] > Math.sqrt(n))
break;
int count = 0;
while (n % nums[i] == 0) {
//SECOND CHANGE: count as an array
count[i]++;
n /= nums[i];
}
}
//SECOND CHANGE: count as an array
for (int i=0; i<count.length; i++) {
if (count[i] %2 != 0) return false;
}
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With