ZOJ Problem Set - 3673 1729

1729

Time Limit: 3 Seconds       Memory Limit: 65536 KB

1729 is the natural number following 1728 and preceding 1730. It is also known as the Hardy-Ramanujan number after a famous anecdote of the British mathematician G. H. Hardyregarding a hospital visit to the Indian mathematician Srinivasa Ramanujan. In Hardy's words:

I remember once going to see him when he was ill at Putney. I had ridden in taxi cab number 1729 and remarked that the number seemed to me rather a dull one, and that I hoped it was not an unfavorable omen. "No," he replied, "it is a very interesting number; it is the smallest number expressible as the sum of two (positive) cubes in two different ways."

The two different ways are these: 1729 = 13 + 123 = 93 + 103

Now your task is to count how many ways a positive number can be expressible as the sum of two positive cubes in. All the numbers in this task can be expressible as the sum of two positive cubes in at least one way.

Input

There're nearly 20,000 cases. Each case is a positive integer in a single line. And all these numbers are greater than 1 and less than 264.

Output

Please refer to the sample output. For each case, you should output a line. First the number of ways n. Then followed by n pairs of integer, (ai,bi), indicating a way the given number can be expressible as the sum of ai's cube and bi's. (ai≤ bi, and a1a2< ...< an)

Sample Input
9
4104
2622104000
21131226514944
48988659276962496
Sample Output
1 (1,2)
2 (2,16) (9,15)
3 (600,1340) (678,1322) (1020,1160)
4 (1539,27645) (8664,27360) (11772,26916) (17176,25232)
5 (38787,365757) (107839,362753) (205292,342952) (221424,336588) (231518,331954)

//zoj 1729

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>


using namespace std;
#define Z 6000000
#define maxn 2642246
typedef unsigned long long ull;




ull prime[Z], np;
bool vis[Z];
ull zys[1010],dycishu[1010];
ull n;
int top;
int len;
struct cc
{
    ull a;
    ull b;
} ans[10000];




int cmp(cc x,cc y)
{
return x.a<y.a;
}








void primebiao()
{
    int i,j;
    np = 0;
    for(i = 2; i<Z; i++)
    {
        if(!vis[i]) prime[np++] = i;
        for(int j = 0; j<np &&  prime[j]*i<Z; j++)
        {
            vis[prime[j]*i] = 1;
            if(i%prime[j]==0) break;
        }
    }
}


ull div(ull m)   //找出n的所有的因子
{
int i;
    ull k;
    len = 0;
    for(i = 0; i<np && prime[i]*prime[i]<=m; i++)
    {
        if(m%prime[i] == 0)
        {
            zys[len] = prime[i];  //保存因子
            k = 1;
            m/=prime[i];
            while(m%prime[i] == 0)
            {
                k++;
                m/=prime[i];
            }
            dycishu[len++] = k;   //每个因子的次数
        }
    }
    if(m>1)    //本身是质数的时候
    {
        zys[len] = m;
        dycishu[len++] = 1;
    }


}




ull quickpow(ull m,ull n)
{
    ull b = 1;
    while (n > 0)
    {
          if (n & 1)
             b = b*m;
          n = n >> 1 ;
          m = m*m;
    }
    return b;
}


ull judge(ull derta)  //要求整数解,b^2-4*a*c必须能开出整数
{
    ull x = sqrt(1.0*derta);
    if(x*x ==derta) return x;
    return Z;
}


int panduanchongfu(ull x,ull y)  //看这组解是否已经存在
{
    for(int i=0; i<top; i++)
        if(ans[i].a==x&&ans[i].b==y)
            return 1;
    return 0;
}






void work(ull t)   //找出解..
{
ull x1,x2;
    ull k = n/t;
    ull r = t*t-k; // a+b=t,(t*t-n/t)/3=p,  a^2-t*a+p=0;
    if(r>0 && r%3!=0) return;
    r/=3;
    ull dis = t*t-4*r;
    if(dis<0) return ;
    ull c = judge(dis);
    if(c == Z) return;


    if((t+c)%2 == 0)
    {
        x1 = (t+c)/2;
        x2 = t-x1;
        if(x1>x2) swap(x1,x2);
        if(x1>0&&x1<t&&x1<maxn&&x2<maxn&&x2>0&&x2<t&&!panduanchongfu(x1,x2))
        {
            ans[top].a=x1;
            ans[top++].b=x2;
        }
    }
    if((t-c)>0 && (t-c)%2 == 0)
    {
        x1 = (t-c)/2;
        x2 = t-x1;
        if(x1>x2) swap(x1,x2);
        if(x1>0&&x1<t&&x1<maxn&&x2<maxn&&x2>0&&x2<t&&!panduanchongfu(x1,x2))
        {
            ans[top].a=x1;
            ans[top++].b=x2;
        }
    }
}








void dfs(ull m,ull sum)
{
    work(sum);
    if(m>=len)  return ;   //len是n的因子的个数,m是代表第m个因子
    for(int i = 0; i<=dycishu[m]; i++)
        dfs(m+1,sum*quickpow(zys[m],i));
}








int main()
{
    //freopen("1.txt","r",stdin);
primebiao();   //打素数表
while(scanf("%llu",&n)!=EOF)
{
div(n);
//for(int i=0;i<len;i++)
// cout<<zys[i]<<' '<<dycishu[i]<<endl;
top=0;
dfs(0,1);
sort(ans,ans+top,cmp);
printf("%d",top);


         for(int i = 0; i<top; i++)
            printf(" (%llu,%llu)",ans[i].a,ans[i].b);
        printf("\n");




}
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值