POJ1811 Prime Test
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
题目链接:POJ1811
正解:$Pollard-rho$
解题报告:
$Pollard-rho$算法模板题。
学习$Pollard-rho$,左转上一篇题解.
//It is made by ljh2000 //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。 #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <vector> #include <ctime> using namespace std; typedef long long LL; vector<LL>w; inline LL mul(LL x,LL y,LL mod){ LL r=0; while(y>0) { if(y&1) r+=x,r%=mod; x+=x; x%=mod; y>>=1; } return r; } inline LL fast_pow(LL x,LL y,LL mod){ LL r=1; while(y>0) { if(y&1) r=mul(r,x,mod); x=mul(x,x,mod); y>>=1; } return r; } inline LL nex(LL x,LL c,LL mod){ return (mul(x,x,mod)+c)%mod; } inline LL gcd(LL x,LL y){ if(y==0) return x; return gcd(y,x%y); } inline LL ABS(LL x){ if(x<=0) return -x; return x; } inline LL Miller_Rabin(LL n){ if(n==1) return 0; if(n==2) return 1; if(!(n&1)) return 0; int T=5; LL aa,nn=n-1,k=0,bb,cc; while(!(nn&1)) nn>>=1,k++; while(T--) { aa=rand()%(n-1)+1; bb=fast_pow(aa,nn,n); for(int i=1;i<=k;i++) { cc=mul(bb,bb,n); if(cc==1 && bb!=1 && bb!=n-1) return 0; bb=cc; } if(bb!=1) return 0; } return 1; } inline void Pollard_rho(LL n){ while(!(n&1)) n>>=1,w.push_back(2); if(n==1) return ; if(Miller_Rabin(n)) { w.push_back(n); return ; } LL x=rand()%(n-1)+1,y=x,c=rand()%(n-1)+1,g; while(1) { bool flag=true; for(int i=1,j=2;;i++) { x=nex(x,c,n); if(x==y) { flag=false; break; } g=gcd(ABS(x-y),n); if(g>1 && g<n) break; if(i==j) y=x,j<<=1; } if(flag) break; } Pollard_rho(n/g); Pollard_rho(g); } inline void work(){ //srand(time(NULL)); srand(1197993966); int T; scanf("%d",&T); LL n; while(T--) { scanf("%lld",&n); if(Miller_Rabin(n)) { puts("Prime"); continue; } w.clear(); Pollard_rho(n); sort(w.begin(),w.end()); printf("%lld\n",w[0]); } } int main() { work(); return 0; } //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!