1593. Square Country. Version 2
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
There live square people in a square country. Everything in this country is square also. Thus, the Square Parliament has passed a law about a land. According to the law each citizen of the country has a right to buy land. A land is sold in squares, surely. Moreover, a length of a square side must be a positive integer amount of meters. Buying a square of land with a side
a one pays
a
2 quadrics (a local currency) and gets a square certificate of a landowner.
One citizen of the country has decided to invest all of his
N quadrics into the land. He can, surely, do it, buying square pieces 1 × 1 meters. At the same time the citizen has requested to minimize an amount of pieces he buys: "It will be easier for me to pay taxes," — he has said. He has bought the land successfully.
Your task is to find out a number of certificates he has gotten.
Input
The only line contains a positive integer
N ≤ 10
15 , that is a number of quadrics that the citizen has invested.
Output
The only line contains a number of certificates that he has gotten.
Sample
input | output |
---|---|
344 | 3 |
Hint
This problem is the same as “
Square country” but with bigger limitations.
Problem Author: Prepared by Fyodor Menshikov, special thanks to Svyatoslav Demidov
Square Country 的加强版本,数据范围加大。要求计算出该正整数最少能够使用多少个正整数的平方和来表示。
定理:n ≠ (4^a)(8m + 7) 是 n 可以用三个平方数表示的一个充分必要条件
定理: 一个数 n 是两个平方之和,当且仅当在 n 的标准分解式中,它的所有形如 4m + 3 的素因子都有偶次幂
我们还有以下定理:
形如 4m + 3 的整数有形如 4m + 3 的素因子
#include <stdio.h>
#include <math.h>
int main()
{
__int64 N,M,k1,k2,x,L;
scanf("%I64d",&N);
if(N==0)
{
printf("0\n");
return 0;
}
k1=(int)sqrt((double)N);
if(k1*k1==N)
{
printf("1\n");
return 0;
}
M=N;
while(M%2==0) M/=2;
if(M%4!=3)
{
if(M==1)
{
printf("2\n");
return 0;
}
L=M;
k1=(int)sqrt((double)M);
M=M-k1*k1;
k2=(int)sqrt((double)M);
for(x=k1; x>=k2; x--)
{
M=L;
M=M-x*x;
k2=(int)sqrt((double)M);
if(k2*k2+x*x==L)
{
printf("2\n");
return 0;
}
}
}
M=N;
while(M%4==0) M=M/4;
if(M%8==7)
{
printf("4\n");
return 0;
}
printf("3\n");
return 0;
}