HDOJ/HDU 3864 多校联合 D_num 数论

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3864

题目:

D_num

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


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<stdio.h> #include<algorithm> #include<iostream> #include<time.h> #include<math.h> #include<stdlib.h> #include<string.h> #define MAX_VAL __int64(1)<<60 #define TIMES 40 #define MAX_L 64n #define CVAL 200 typedef __int64 LL; using namespace std; LL minfactor; LL multandmod(LL a,LL b,LL n) { a=a%n; LL res=0; while(b) { if(b&1) { res=res+a; if(res>=n) res=res-n; } a=a<<1; if(a>=n) a=a-n; b=b>>1; } return res; } LL modandexp(LL a,LL b,LL n) { a=a%n; LL res=1; while(b>=1) { if(b&1) res=multandmod(res,a,n); a=multandmod(a,a,n); b=b>>1; } return res; } bool millerRobin(LL a,LL n) { LL u=0,cur=n-1; int t=0; bool find1=false; while(cur!=0) { if(!find1) { int pb=cur%2; if(pb==0) t++; else find1=true; } if(find1) break; cur=cur/2; } u=cur; cur=modandexp(a,u,n); LL now; for(int p=1;p<=t;p++) { now=modandexp(cur,2,n); if(cur!=1&&now==1&&cur!=n-1) { return false; } cur=now; } if(cur!=1) return false; return true; } bool testprime(int times,LL n) { if(n==2) return true; if(n%2==0) return false; LL a;int t; srand(time(NULL)); for(t=1;t<=times;t++) { a=rand()%(n-1)+1; if(!millerRobin(a,n)) return false; } return true; } LL gcd(LL a,LL b) { if(b==0) return a; else return gcd(b,a%b); } LL pollardrho(LL n,int c) { int i=1; srand(time(NULL)); LL x=rand()%n; LL y=x; int k=2; while(true) { i=i+1; x=(modandexp(x,2,n)+c)%n; LL d=gcd(y-x,n); if(1<d&&d<n) return d; if(y==x) return n; if(i==k) { y=x; k=k*2; } } } void getsmallst(LL n,int c) { if(n==1) return; if(testprime(TIMES,n)) { if(n<minfactor) minfactor=n; return; } LL val=n; while(val==n) val=pollardrho(n,c--); getsmallst(val,c); getsmallst(n/val,c); } int main() { LL n; while(scanf("%I64d",&n)!=EOF) { minfactor=MAX_VAL; if(n==1) { printf("is not a D_num\n"); continue; } if(testprime(TIMES,n)) printf("is not a D_num\n"); else { getsmallst(n,CVAL); if(minfactor*minfactor*minfactor==n) { printf("%I64d %I64d %I64d\n",minfactor,minfactor*minfactor,n); continue; } if(minfactor*minfactor==n) { printf("is not a D_num\n"); continue; } if(testprime(TIMES,n/minfactor)) printf("%I64d %I64d %I64d\n",minfactor,n/minfactor,n); else printf("is not a D_num\n"); } } return 0; }



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值