题目链接: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
Gcd is Greatest common divisor.
Each line have a numeral N(1<=N<10^18)
题目意思很简单了主要难的地方在于数据量太大,所以必须用随机算法
但是要注意一种特殊情况,及某质数的三次方。
我的代码:
#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; }