hdu 3864 D_num

D_num

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2023    Accepted Submission(s): 561


Problem Description
Oregon Maple was waiting for Bob When Bob go back home. Oregon Maple asks Bob a problem that as a Positive number N, if there are only four Positive number M makes Gcd(N, M) == M then we called N is a D_num. now, Oregon Maple has some Positive numbers, and if a Positive number N is a D_num , he want to know the four numbers M. But Bob have something to do, so can you help Oregon Maple? 
Gcd is Greatest common divisor.
 

Input
Some cases (case < 100);
Each line have a numeral N(1<=N<10^18)
 

Output
For each N, if N is a D_NUM, then output the four M (if M > 1) which makes Gcd(N, M) = M. output must be Small to large, else output “is not a D_num”.
 

Sample Input
  
  
6 10 9
 

Sample Output
  
  
2 3 6 2 5 10 is not a D_num
 

Source
 

Recommend
lcy
 

唉  水人的水题做法:

#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    __int64 i,n,res;
    while(scanf("%I64d",&n)!=EOF)
    {
        int ans=0;
        for(i=2;i<=4000000&&i<=sqrt(n*1.0);i++)
        {
            if(n%i==0)
            {
                res=i;
                if(i!=n/i)
                ans+=2;
                else
                ans++;
            }
            if(ans>2)
            break;
        }
        if(ans!=2)
        printf("is not a D_num\n");
        else
        printf("%I64d %I64d %I64d\n",res,n/res,n);
    }
    return 0;
}

好点的方法 唉    目测还是只能看别人的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#define MAXN 1000000
__int64 factor;
bool mark[MAXN + 1];
int prime[MAXN + 1];
int cnt;

__int64 Mul(__int64 a, __int64 b, __int64 n){
    __int64 ans = 0;
    while (b){
        if (b & 1){
            ans = (ans + a) % n;
        }
        a = (a + a) % n;
        b = b >> 1;
    }
    return ans;
}

__int64 Pow(__int64 a, __int64 b, __int64 n)
{
    __int64 ans = 1;
    while (b){
        if (b & 1){
            ans = Mul(ans, a, n);
        }
        a = Mul(a, a, n);
        b =  b >> 1;
    }
    return ans;
}

bool IsPrime(__int64 n, __int64 a)
{
    __int64 t, d;
    d = n - 1;
    while ((d & 1) == 0) d >>= 1;
    t = Pow(a, d, n);
    while (t != 0 && t != 1 && t != n - 1 && d < n - 1)
    {
        t = Mul(t, t, n);
        d <<= 1;
    }
    return ((t == n - 1) || (d & 1) && t > 0);
}

bool Prime(__int64 n){
    if (n <= MAXN) return !mark[n];

    if (IsPrime(n, 2)
        && IsPrime(n, 3)
         && IsPrime(n, 7)
        && IsPrime(n, 61)
        && IsPrime(n, 24251)
           && IsPrime(n,  rand() % n)
       )
        return true;
    else return false;
}

__int64 gcd(__int64 a, __int64 b){
    __int64 c;
    if(a<0)
    a=-a;
    while(a){
        c = b % a;
        b = a;
        a = c;
    }
    return b;
}

void POLLARD_RHO(__int64 n, __int64 c){
    int i, k;
    __int64 x, y, d;
    __int64 p = (int)(double)sqrt((double)n);
    k = 1;
    x = (__int64)rand() * rand() % n;
    y = x;
    for (i = 2; i <= p; i++){
        x = (Mul(x, x, n) - c + n) % n;
        d = gcd(y - x, n);
        if (d != 1 && d != n){
            factor = d;
            return;
        }
        if (i == (1 << k)){
            y = x;
            k++;
        }
    }
}

void makeprime()
{
    int i, j;
    cnt = 0;
    memset(mark, 0, sizeof(mark));
    for (i = 2; i <= MAXN; i++)
    {
        if (!mark[i])
            prime[++cnt] = i;
        for (j = 1; j <= cnt && i * prime[j] <= MAXN; j++)
        {
            mark[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

int main(){
    __int64 n, c;
    srand((int)time(NULL));
    makeprime();
    while(scanf("%I64d", &n) == 1){
        if (Prime(n)){
            printf("is not a D_num\n");
            continue;
        }
        factor = n;
        while(!Prime(factor)){
            while(c = (__int64)rand() * rand() % factor, c <= 1);
            POLLARD_RHO(factor, c);
        }
        if ((Prime(n / factor) || factor * factor == n / factor) && factor != n / factor){
            if (factor > n / factor)
                printf("%I64d %I64d %I64d\n", n / factor, factor, n);
            else
                printf("%I64d %I64d %I64d\n", factor, n / factor, n);
        }else{
            printf("is not a D_num\n");
        }
    }
    return 0;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值