Ural 1593. Square Country. Version 2 Lagrange 定理

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

n ≠ 4 a(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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值