Pollard's Rho演算法總結
阿新 • • 發佈:2019-01-02
先貼一份程式碼在這。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cctype> #include <algorithm> #include <ctime> #define rin(i,a,b) for(int i=(a);i<=(b);i++) #define rec(i,a,b) for(int i=(a);i>=(b);i--) #define trav(i,a) for(int i=head[(a)];i;i=e[i].nxt) typedef long long LL; using std::cin; using std::cout; using std::endl; inline LL read(){ LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } LL n,ans,mi[6]={2,3,5,7,11,13}; inline LL gcd(LL x,LL y){ if(!x||!y) return x+y; while(y){ std::swap(x,y); y%=x; } return x; } inline LL qpow(LL x,LL y,LL mod){ LL ret=1,tt=x%mod; while(y){ if(y&1) ret=(__int128)ret*tt%mod; tt=(__int128)tt*tt%mod; y>>=1; } return ret; } bool miller_rabin(LL num){ if(num<2) return 0; if(num==2||num==3||num==5||num==7||num==11||num==13) return 1; if(num%2==0||num%3==0||num%5==0||num%7==0||num%11==0||num%13==0) return 0; LL temp=num-1;int cnt2=0; while(!(temp&1)) temp>>=1,cnt2++; rin(i,0,5){ LL now=qpow(mi[i],temp,num); if(now==1||now==num-1) continue; rin(j,1,cnt2){ now=(__int128)now*now%num; if(now==num-1) break; if(j==cnt2) return 0; } } return 1; } LL pollard_rho(LL num){ LL fixx=rand()%(num-1)+1,siz=2,x=fixx,fac=1; LL b=rand()%(num-1)+1; while(fac==1){ rin(i,1,siz){ x=((__int128)x*x+b)%num; fac=gcd(std::abs(x-fixx),num); if(fac>1) return fac; } siz<<=1; fixx=x; } } void getdivisor(LL num){ if(num==1||num<=ans) return; if(miller_rabin(num)){ ans=std::max(ans,num); return; } LL x=num; while(x==num) x=pollard_rho(x); while(num%x==0) num/=x; if(num<x) std::swap(num,x); getdivisor(num); getdivisor(x); } int main(){ int T=read(); while(T--){ n=read(); ans=1; getdivisor(n); if(ans==n) printf("Prime\n"); else printf("%lld\n",ans); } return 0; }