Ural 1593. Square Country. Version 2 Lagrange 定理

来源:互联网 发布:大数据光环骗局 编辑:程序博客网 时间:2024/06/05 01:16

1593. Square Country. Version 2

Time limit: 1.0 second
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 a2 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 ≤ 1015 , 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

inputoutput
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 的素因子

n ≠ 4a(8m + 7) 是 n 可以用三个平方数表示的一个充分必要条件

#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;}


原创粉丝点击