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
",w[0]);
	}
}

int main()
{
    work();
    return 0;
}
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

  

原文地址:https://www.cnblogs.com/ljh2000-jump/p/6609894.html