標籤:數學
連結:http://acm.hdu.edu.cn/showproblem.php?pid=3864
題意:給出一個數N(1<=N<10^18),如果N只有四個約數,就輸出除1外的三個約數。
思路:大數的質因數分解只能用隨機演算法Miller Rabin和Pollard_rho,在測試多的情況下正確率是由保證的。
代碼:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <cstdlib>#include <queue>#include <stack>#include <vector>#include <ctype.h>#include <algorithm>#include <string>#include <set>#include <ctime>#define PI acos(-1.0)#define INF 0x7fffffff#define eps 1e-8#define maxn 50005typedef __int64 LL;typedef unsigned long long ULL;using namespace std;LL Factor[100];int t=0;LL mul_mod(LL a,LL b,LL n){ a=a%n; b=b%n; LL s=0; while(b) { if(b&1) s=(s+a)%n; a=(a<<1)%n; b=b>>1; } return s;}LL pow_mod(LL a,LL b,LL n)//求a^b%n{ a=a%n; LL s=1; while(b) { if(b&1) s=mul_mod(s,a,n); a=mul_mod(a,a,n); b=b>>1; } return s;}bool isPrime(LL n, LL times){ if(n==2)return 1; if(n<2||!(n&1))return 0; LL a, u=n-1, x, y; int t=0; while(u%2==0) { t++; u/=2; } srand(100); for(int i=0; i<times; i++) { a = rand() % (n-1) + 1; x = pow_mod(a, u, n); for(int j=0; j<t; j++) { y = mul_mod(x, x, n); if ( y == 1 && x != 1 && x != n-1 ) return false; //must not x = y; } if( y!=1) return false; } return true;}LL gcd(LL a,LL b){ if(a==0) return 1; if(a<0) return gcd(-a,b); return b==0?a:gcd(b,a%b);}LL Pollard_rho(LL n,LL c)//Pollard_rho演算法,找出n的因子{ LL i=1,j,k=2,x,y,d,p; x=rand()%n; y=x; while(true) { i++; x=(mul_mod(x,x,n)+c)%n; if(y==x)return n; if(y>x)p=y-x; else p=x-y; d=gcd(p,n); if(d!=1&&d!=n)return d; if(i==k) { y=x; k+=k; } }}void factor(LL n){ if(isPrime(n,20)) { Factor[t++]=n; return; } LL p=n; while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1); factor(p); factor(n/p);}void solve(LL a){ if(a==1) { printf("is not a D_num\n"); return; } t=0; factor(a); sort(Factor,Factor+t); if(t==2) { if(Factor[0]!=Factor[1]) { printf("%I64d %I64d %I64d\n",Factor[0],Factor[1],a); } else printf("is not a D_num\n"); } else if(t==3) { if(Factor[0]==Factor[1]&&Factor[1]==Factor[2]) printf("%I64d %I64d %I64d\n",Factor[0],Factor[0]*Factor[1],a); else printf("is not a D_num\n"); } else printf("is not a D_num\n");}int main(){ LL a; while(~scanf("%I64d",&a)) { solve(a); } return 0;}